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:
- Generate a random UUID
- Generate random captcha images and results
- Store the UUID and captcha results in Redis
- 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
- Ruoyi in default uuid for Version 4, have a probability of repeat www.zhihu.com/question/34…
- Ruoyi uses ThreadLocalRandom to generate random numbers to avoid multi-thread competition
- 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