Session management and generation of verification code

Posted by Danosaur on Wed, 23 Feb 2022 15:20:31 +0100

session management

Cookie introduction

https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Cookies

HTTP Cookie (also known as Web Cookie or browser cookie) is a small piece of data sent by the server to the user's browser and saved locally. It will be carried and sent to the server the next time the browser sends a request to the same server. Usually, it is used to tell the server whether two requests come from the same browser, such as maintaining the user's login status. Cookie based Stateless It is possible for HTTP protocol to record stable status information.

Cookie s are mainly used in the following three aspects:

  • Session state management (such as user login status, shopping cart, game score or other information to be recorded)
  • Personalized settings (such as user-defined settings, themes, etc.)
  • Browser behavior tracking (such as tracking and analyzing user behavior)

1. The browser sends a request to the server for the first time, and the server accepts the request and puts a cookie on the response header;

2. The browser receives the response from the server and creates a cookie locally;

3. The second time the browser sends a request to the server, it will bring the previous cookie

//Specify the path. All methods under Test are accessed under this path
@Controller
@RequestMapping("/Test")
public class TestController {


    //First request to set a cookie
    @RequestMapping(path = "/cookie/set",method = RequestMethod.GET)
    @ResponseBody
    public String setCookie(HttpServletResponse httpServletResponse)
    {
        //Create a new cookie and store a random string
        Cookie cookie=new Cookie("code", CommunityUtil.generateUUID());
        //Set the access path of the cookie. Only when you access these paths will you bring the cookie
        cookie.setPath("/community/Test");
        //Set cookie lifetime in seconds
        cookie.setMaxAge(60*10);
        //Add a cookie to the response and send the cookie
        httpServletResponse.addCookie(cookie);

        return "set cookie";
    }


    //Second request to obtain cookie
    //@Cookie value gets the corresponding cookie value
    @RequestMapping(path = "/cookie/get",method = RequestMethod.GET)
    @ResponseBody
    public String getCookie(@CookieValue("code") String code)
    {
        System.out.println(code);
        return "get cookie";
    }
}

Session

The Session is stored on the server side, which is more secure, but it will increase the memory pressure of the server

// session example

@RequestMapping(path = "/session/set", method = RequestMethod.GET)
@ResponseBody
public String setSession(HttpSession session) {
    session.setAttribute("id", 1);
    session.setAttribute("name", "Test");
    return "set session";
}

@RequestMapping(path = "/session/get", method = RequestMethod.GET)
@ResponseBody
public String getSession(HttpSession session) {
    System.out.println(session.getAttribute("id"));
    System.out.println(session.getAttribute("name"));
    return "get session";
}

Distributed session sharing scheme:

1. Sticky session: a consistent hash strategy is provided in nginx, which can keep the hash value calculation of user ip fixed and distributed to a server, and the load is relatively balanced. The problem is that if a server hangs, the session is also lost.

2. Synchronous session: when a server saves a session and synchronizes it to other servers, the problem is that synchronizing a session to other servers will affect the performance of the server, and the coupling between servers is strong.

3. Shared session: a separate server is used to store sessions, and other servers obtain sessions from this server. The problem is that if this server hangs, all sessions will be lost.

4. Redis centralized management session (mainstream method): redis is an in memory database with high reading and writing efficiency, and can be highly available in the cluster environment.

Generate verification code

-Import jar package

<!-- https://mvnrepository.com/artifact/com.github.penggle/kaptcha -->
<dependency>
    <groupId>com.github.penggle</groupId>
    <artifactId>kaptcha</artifactId>
    <version>2.3.2</version>
</dependency>

-Write Kaptcha configuration class

@Configuration
public class KaptchaConfig {

    @Bean
    public Producer kaptchaProducer() {
        Properties properties = new Properties();
        //Width of verification code image
        properties.setProperty("kaptcha.image.width", "100");
        //Image verification code height
        properties.setProperty("kaptcha.image.height", "40");
        //Font size of verification code generation
        properties.setProperty("kaptcha.textproducer.font.size", "32");
        properties.setProperty("kaptcha.textproducer.font.color", "0,0,0");
        //Range of letters generated by verification code
        properties.setProperty("kaptcha.textproducer.char.string", "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYAZ");
        //Length of verification code
        properties.setProperty("kaptcha.textproducer.char.length", "4");
        
        //Distortion and stretching of interference pictures
        properties.setProperty("kaptcha.noise.impl", "com.google.code.kaptcha.impl.NoNoise");

        DefaultKaptcha kaptcha = new DefaultKaptcha();
        //Load configuration information
        Config config = new Config(properties);
        kaptcha.setConfig(config);
        return kaptcha;
    }

}

-Generate random characters and pictures

-Write a request to return the verification code picture

  • The text generated by the verification code needs to be saved to verify whether the verification code is correctly entered and needs to be passed between multiple values. Therefore, set session to save the verification code
  • Mr. Cheng into verification code text, generating pictures
  • Output pictures to browser using byte stream
  • You don't have to close the flow manually, and the response will close
//Generate verification code
@RequestMapping(value = "/Kaptcha",method = RequestMethod.GET)
public void getKaptcha(HttpServletResponse httpServletResponse, HttpSession session) {
    // Generate verification code
    String text = kaptchaProducer.createText();
    BufferedImage image = kaptchaProducer.createImage(text);

    //Save verification code to session
    session.setAttribute("KaptchaCode",text);

    //Output pictures to browser
    httpServletResponse.setContentType("image/png");

    try {
        ServletOutputStream outputStream = httpServletResponse.getOutputStream();
        ImageIO.write(image,"png",outputStream);
    } catch (IOException e) {
        e.printStackTrace();
    }
}

Achieve refresh effect

  • Modify picture access path
  • Use jquery to write a method to refresh the verification code
  • js defines a global variable project name for easy modification
  • P="+Math.random(); prevent the browser from mistakenly thinking that the request path has not changed and not sending the request, resulting in failure to refresh
var CONTEXT_PATH="/community";
<div class="col-sm-4">
   <img th:src="@{/Kaptcha}"  id="kaptcha"  style="width:100px;height:40px;" class="mr-2"/>
   <a href="javascript:refresh_Kaptcha();" class="font-size-12 align-bottom">Refresh verification code</a>
</div>

<script >
   function refresh_Kaptcha() {
      var path=CONTEXT_PATH+"/Kaptcha?P="+Math.random();
      $("#kaptcha").attr("src",path);

   }
</script>

DEBUG

At the beginning of writing the cookie, there was a problem that Thymeleaf resolved the address incorrectly. It was found that the path of the cookie was set incorrectly, and the project path should be added

cookie.setPath("/community/Test");

Topics: Front-end Back-end server http