Although this blog talks about the call of ruoyi’s back-end code, looking at the front-end code can help with understanding, so in this blog I will first introduce the front-end code, and then talk about the implementation of the back-end.
Table of Contents
1. Verification code
1.1 Front end
1.2 Backend
2. Log in
2.1 Front-end
2.2 Backend
3. Log out
1.Verification code
We first pulled up ruoyi, opened the inspection tool, and checked the requests. We found that there were two requests just after we opened the page.
So what needs to be requested from the backend to open the login page? The request that passes the analysis is a verification code.
1.1 front end
We found the content about the verification code request on the front end. We found that the front end obtained the picture information of the verification code from the back-end API and then rendered it to the front-end page.
1.2 backend
Then let’s look at the code for the backend verification code:
// Use the GET request mapped to the controller method of the "/captchaImage" path to obtain the verification code image @GetMapping("/captchaImage") public AjaxResult getCode(HttpServletResponse response) throws IOException { //Create a successful AjaxResult object AjaxResult ajax = AjaxResult.success(); //Query whether the verification code function is enabled boolean captchaOnOff = configService.selectCaptchaOnOff(); // Add the "captchaOnOff" field to the response to indicate whether the verification code is enabled ajax.put("captchaOnOff", captchaOnOff); // If the verification code function is not enabled, return AjaxResult directly if (!captchaOnOff) { return ajax; } // Generate verification code String uuid = IdUtils.simpleUUID(); // Generate a UUID, usually used for verification code verification String verifyKey = Constants.CAPTCHA_CODE_KEY + uuid; // Construct the storage key of the verification code String capStr = null, code = null; BufferedImage image = null; // Generate verification code based on configured verification code type String captchaType = RuoYiConfig.getCaptchaType(); if ("math".equals(captchaType)) { // Mathematical verification code String capText = captchaProducerMath.createText(); capStr = capText.substring(0, capText.lastIndexOf("@")); code = capText.substring(capText.lastIndexOf("@") + 1); image = captchaProducerMath.createImage(capStr); } else if ("char".equals(captchaType)) { //Character verification code capStr = code = captchaProducer.createText(); image = captchaProducer.createImage(capStr); } // Store the verification code in the Redis cache and set the expiration time redisCache.setCacheObject(verifyKey, code, Constants.CAPTCHA_EXPIRATION, TimeUnit.MINUTES); //Convert the verification code image to Base64 encoding for display on the front end FastByteArrayOutputStream os = new FastByteArrayOutputStream(); try { ImageIO.write(image, "jpg", os); } catch (IOException e) { return AjaxResult.error(e.getMessage()); } // Store the Base64 encoding of UUID and verification code image in AjaxResult and return ajax.put("uuid", uuid); ajax.put("img", Base64.encode(os.toByteArray()); return ajax; }
These two methods work together to allow the system to control the on/off status of the verification code function based on parameters in the configuration file, so that verification code verification can be enabled or disabled when needed. The method selectConfigByKey
is responsible for obtaining specific configuration values from the cache or database, while the method selectCaptchaOnOff
determines whether the verification code is enabled.
2.Login
After the user successfully enters the username, password and verification code, click the login button.
2.1 front end
The front end needs to send a request to the back end asynchronously, and use post to request the user name, password and verification code to the back end.
Encapsulate the passed data into data, Then return means making a post request to the url with data data.
Then we found that the user had an extra token after logging in.
2.2 backend
We can find in the back-end interface that what is obtained in loginBody is the content written by the front-end.
public String login(String username, String password, String code, String uuid) { // Check the verification code switch status boolean captchaOnOff = configService.selectCaptchaOnOff(); // If the verification code switch is turned on, perform verification code verification if (captchaOnOff) { validateCaptcha(username, code, uuid); } // User Authentication Authentication authentication = null; try { // Call authenticationManager for user authentication, usually calling the UserDetailsServiceImpl.loadUserByUsername method authentication = authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(username, password)); } catch (Exception e) { // Handle user verification exceptions, usually catching BadCredentialsException exceptions indicating incorrect passwords if (e instanceof BadCredentialsException) { //Record login failure information and throw user password mismatch exception AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.password.not.match"))); throw new UserPasswordNotMatchException(); } else { //Record login failure information and throw ServiceException AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, e.getMessage())); throw new ServiceException(e.getMessage()); } } //Record login success information AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success"))); // Get login user information from the Authentication object LoginUser loginUser = (LoginUser) authentication.getPrincipal(); //Record login information recordLoginInfo(loginUser.getUserId()); // Generate and return the token of the logged in user return tokenService.createToken(loginUser); }
When the verification code and user’s account password are all verified, the login is successful!