This is the third day of my participation in the November Gwen Challenge. Check out the details: the last Gwen Challenge 2021

preface

This section introduces the code of SysLoginController in ruoyi-Vue’s ruoyi-admin module. Today we will explain the logic of login here. Ruoyi-vue uses the Spring-Security framework as the permission control framework. Then we need to write code that meets the requirements of Spring-Security so that we can use it well.

The login code

public String login(String username, String password, String code, String uuid) {
    boolean captchaOnOff = configService.selectCaptchaOnOff();
    // Verification code switch
    if (captchaOnOff) {
        validateCaptcha(username, code, uuid);
    }
    // User authentication
    Authentication authentication = null;
    try {
        / / this method will be to call UserDetailsServiceImpl loadUserByUsername
        authentication = authenticationManager
                .authenticate(new UsernamePasswordAuthenticationToken(username, password));
    } catch (Exception e) {
        if (e instanceof BadCredentialsException) {
            AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.password.not.match")));
            throw new UserPasswordNotMatchException();
        } else {
            AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, e.getMessage()));
            throw new ServiceException(e.getMessage());
        }
    }
    AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success")));
    LoginUser loginUser = (LoginUser) authentication.getPrincipal();
    recordLoginInfo(loginUser.getUser());
    / / token is generated
    return tokenService.createToken(loginUser);
}
Copy the code

Verification code switch

Actual production environment, in order to prevent malicious users to keep log in blasting, we need to use the verification code to log in to limit, but for the test environment for selenium and other tools for pressure measurement or test automation, testers need corresponding authentication code we will shut down, then the authentication code switch are very useful, Captcha can be turned on and off without issuing a version.

Authentication

Authentication stores the passed the AuthenticationManager. Authenticate (Authentication) method requests the data returned (is a SecurityContextHolder management thread – local SecurityContext), we can see in the above code is UsernamePasswordAuthenticationToken this, So what calls a method, we can see from the comments is in UserDetailsServiceImpl loadUserByUsername here, so the spring – how do you know to invoke this service security of this method? The corresponding userDetailsService is injected into the authentication interface using the following code in the SecurityConfig class

/** * Authentication interface */
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
    auth.userDetailsService(userDetailsService).passwordEncoder(bCryptPasswordEncoder());
}
Copy the code

Corresponding to this you can see the loadUserByUsername method in the interface that we have to implement

The implementation of the method we can write our own logic, the return object must beUserDetailsSubclass of, we have hereLoginUserThis class.