若依前后端不分离登录大致代码

前端:

地址:ruoyi-ui/src/views/login.vue中的方法

下面这个就是登陆方法,看我注解。this.$store.dispatch是调用vuex中actions中的方法,是vuex相关知识。

handleLogin() {
  this.$refs.loginForm.validate(valid => {
    if (valid) {
      this.loading = true;
      //判断是否勾选记住密码的操作
      if (this.loginForm.rememberMe) {
        Cookies.set("username", this.loginForm.username, { expires: 30 });
        Cookies.set("password", encrypt(this.loginForm.password), { expires: 30 });
        Cookies.set('rememberMe', this.loginForm.rememberMe, { expires: 30 });
      } else {
      //没勾选直接移除就行了
        Cookies.remove("username");
        Cookies.remove("password");
        Cookies.remove('rememberMe');
      }
      //登陆方法
      this.$store.dispatch("Login", this.loginForm).then(() => {
        this.$router.push({ path: this.redirect || "/" }).catch(()=>{});
      }).catch(() => {
        this.loading = false;
        if (this.captchaEnabled) {
          this.getCode();
        }
      });
    }
  });
}

进vuex,res是后端返回的数据,这块应该是把token存到cookies和vuex中了。前端大概就这样。

// 登录
Login({ commit }, userInfo) {
  const username = userInfo.username.trim()
  const password = userInfo.password
  const code = userInfo.code
  const uuid = userInfo.uuid
  return new Promise((resolve, reject) => {
    login(username, password, code, uuid).then(res => {
    //保存token
      setToken(res.token)
      commit('SET_TOKEN', res.token)
      resolve()
    }).catch(error => {
      reject(error)
    })
  })
},

后端:

controller

/**
 * 登录方法
 * 
 * @param loginBody 登录信息
 * @return 结果
 */
@PostMapping("/login")
public AjaxResult login(@RequestBody LoginBody loginBody)
{
    AjaxResult ajax = AjaxResult.success();
    // 生成令牌
    String token = loginService.login(loginBody.getUsername(), loginBody.getPassword(), loginBody.getCode(),
            loginBody.getUuid());
    ajax.put(Constants.TOKEN, token);
    return ajax;
}

service

我就说验证码校验,修改用户表,生成token,其他我也看不懂。

/**
 * 登录验证
 * 
 * @param username 用户名
 * @param password 密码
 * @param code 验证码
 * @param uuid 唯一标识
 * @return 结果
 */
public String login(String username, String password, String code, String uuid)
{
    // 验证码校验
    validateCaptcha(username, code, uuid);
    // 登录前置校验
    loginPreCheck(username, password);
    // 用户验证
    Authentication authentication = null;
    try
    {
        UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(username, password);
        AuthenticationContextHolder.setContext(authenticationToken);
        // 该方法会去调用UserDetailsServiceImpl.loadUserByUsername
        authentication = authenticationManager.authenticate(authenticationToken);
    }
    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());
        }
    }
    finally
    {
        AuthenticationContextHolder.clearContext();
    }
    //insert插入
    AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success")));
    LoginUser loginUser = (LoginUser) authentication.getPrincipal();
    //修改用户表
    recordLoginInfo(loginUser.getUserId());
    // 生成token
    return tokenService.createToken(loginUser);
}

验证码校验,从redis中拿不到验证码,就说明验证码过期了,没过期就直接删除,因为已经拿到验证码的值了,然后再判断验证码是否错误。

/**
 * 校验验证码
 * 
 * @param username 用户名
 * @param code 验证码
 * @param uuid 唯一标识
 * @return 结果
 */
public void validateCaptcha(String username, String code, String uuid)
{
    boolean captchaEnabled = configService.selectCaptchaEnabled();
    if (captchaEnabled)
    {
        String verifyKey = CacheConstants.CAPTCHA_CODE_KEY + StringUtils.nvl(uuid, "");
        String captcha = redisCache.getCacheObject(verifyKey);
        //验证码过期
        if (captcha == null)
        {
            AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.jcaptcha.expire")));
            throw new CaptchaExpireException();
        }
        //验证码拿到后就可以删除了
        redisCache.deleteObject(verifyKey);
        //判断验证码是否错误
        if (!code.equalsIgnoreCase(captcha))
        {
            AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.jcaptcha.error")));
            throw new CaptchaException();
        }
    }
}

修改用户表,主要修改登陆ip,登录时间这两个。

/**
 * 记录登录信息
 *
 * @param userId 用户ID
 */
public void recordLoginInfo(Long userId)
{
    SysUser sysUser = new SysUser();
    sysUser.setUserId(userId);
    //获取ip
    sysUser.setLoginIp(IpUtils.getIpAddr());
    //获取当前时间
    sysUser.setLoginDate(DateUtils.getNowDate());
    //更新用户信息
    userService.updateUserProfile(sysUser);
}

生成token,其实把用户信息也存到redis中了,默认有效期半个小时,水平有限就这样吧

/**
 * 创建令牌
 *
 * @param loginUser 用户信息
 * @return 令牌
 */
public String createToken(LoginUser loginUser)
{
    String token = IdUtils.fastUUID();
    loginUser.setToken(token);
    setUserAgent(loginUser);
    //刷新token,用户信息也会存到redis中,有效期半个小时(存验证码和登陆的用户信息)
    refreshToken(loginUser);

    Map claims = new HashMap<>();
    claims.put(Constants.LOGIN_USER_KEY, token);
    return createToken(claims);
}

你可能感兴趣的:(okhttp)