preface

After the previous two installments, we understood the process of ruoyi’s front-end login page. In this installment, we’ll start looking at the back-end corresponding processes. This paper mainly analyzes the interface for obtaining verification code captchaImage and login interface.

If according to the back-end structure

First let’s take a look at the module composition of ruoyi’s back end.

  • Admin – Web service entry
  • Common — Common tools
  • Framework — Core modules
  • Generator — Code generation
  • Quartz — Timed tasks
  • System — System module

In the ruoyi backend, the Controller file is put into the admin module.

Captcha interface

Corresponding to the file location for ruoyi – admin/SRC/main/Java/com/ruoyi/web/controller/common/CaptchaController. Java

The main process is:

  1. Generate a random UUID
  2. Generate random captcha images and results
  3. Store the UUID and captcha results in Redis
  4. Place the captcha picture into the return value
@GetMapping("/captchaImage")
// AjaxResult returns the same value
public AjaxResult getCode(HttpServletResponse response) throws IOException
{
    // Save the verification code information
    // Use an encrypted strong pseudo-random number generator to generate this UUID
    String uuid = IdUtils.simpleUUID();
    String verifyKey = Constants.CAPTCHA_CODE_KEY + uuid;
​
    String capStr = null, code = null;
    BufferedImage image = null;
​
    // Generate a verification code
    // Apply. Yml to ruoyi. CaptchaType
    // Mathematical model
    if ("math".equals(captchaType))
    {
        String capText = captchaProducerMath.createText();
        / / expression
        capStr = capText.substring(0, capText.lastIndexOf("@"));
        // The corresponding result
        code = capText.substring(capText.lastIndexOf("@") + 1);
        // Generate the image BufferedImage from the expression
        image = captchaProducerMath.createImage(capStr);
    }
    // Text mode
    else if ("char".equals(captchaType))
    {
        // The generated expression is the same as the result
        capStr = code = captchaProducer.createText();
        image = captchaProducer.createImage(capStr);
    }
    // Store the UUID and captcha key values in redis
    redisCache.setCacheObject(verifyKey, code, Constants.CAPTCHA_EXPIRATION, TimeUnit.MINUTES);
    // Convert the flow information to write
    FastByteArrayOutputStream os = new FastByteArrayOutputStream();
    try
    {
        ImageIO.write(image, "jpg", os);
    }
    catch (IOException e)
    {
        return AjaxResult.error(e.getMessage());
    }
​
    AjaxResult ajax = AjaxResult.success();
    ajax.put("uuid", uuid);
    // Switch to base64 format
    ajax.put("img", Base64.encode(os.toByteArray()));
    return ajax;
}
Copy the code
  1. Ruoyi in default uuid for Version 4, have a probability of repeat www.zhihu.com/question/34…
  2. Ruoyi uses ThreadLocalRandom to generate random numbers to avoid multi-thread competition
  3. Ruoyi provides more secure random code generation, but reduces performance

Login interface

Corresponding to the file location is: ruoyi – admin/SRC/main/Java/com/ruoyi/web/controller/system/SysLoginController. Java

@PostMapping("/login")
public AjaxResult login(@RequestBody LoginBody loginBody)
{
    AjaxResult ajax = AjaxResult.success();
    // Generate a token
    String token = loginService.login(loginBody.getUsername(), loginBody.getPassword(), loginBody.getCode(),
            loginBody.getUuid());
    ajax.put(Constants.TOKEN, token);
    return ajax;
}
Copy the code

The previous code doesn’t say much, which is to generate the token and then return it.

Take a look at the token generation process. I’ve removed the exception handling code for your convenience.

public String login(String username, String password, String code, String uuid)
{
    String verifyKey = Constants.CAPTCHA_CODE_KEY + uuid;
    // Obtain the uUID verification code from redis
    String captcha = redisCache.getCacheObject(verifyKey);
    redisCache.deleteObject(verifyKey);
    // CaptCHA is null
    // code does not equal capTCHA exception
  
    // User authentication
    Authentication authentication = null;
   / / this method will be to call UserDetailsServiceImpl loadUserByUsername
  / / call org. Springframework. Security authentication
     authentication = authenticationManager
    .authenticate(new UsernamePasswordAuthenticationToken(username, password));
    // The user does not exist or the password is incorrect
    // Other exceptions
  // Record the login information asynchronously
  AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success")));
    // Get user information and permissions
    LoginUser loginUser = (LoginUser) authentication.getPrincipal();
    // Change the last login IP address and time
    recordLoginInfo(loginUser.getUser());
    / / token is generated
    return tokenService.createToken(loginUser);
}
Copy the code

The next plan

After a user logs in, the/Index page is displayed by default. We look at SRC /views/index.vue and find that most of the content is static. But when you enter this page, you get two requests getInfo and getRouters. These two requests are called by access restriction router.beforeeach in Article 2 – Route Interception jump. The next installment will start with a look at getInfo.

  • Analyze and obtain user information