1.首先在yml配置文件中设置token配置参数
# token配置 token: # 是否允许账户多终端同时登录(true允许 false不允许) soloLogin: false
2.其次在package com.lanbu.common.constant;中添加全局参数
/** * 登录用户编号 redis key */ public static final String LOGIN_USERID_KEY = "login_userid:";
3、在com.zhdj.framework.web.service.TokenService.java中,调整存储&刷新缓存用户编号信息
路径:
// 是否允许账户多终端同时登录(true允许 false不允许) @Value("${token.soloLogin}") private boolean soloLogin; /** * 删除用户身份信息 */ public void delLoginUser(String token, Long userId) { if (StringUtils.isNotEmpty(token)) { String userKey = getTokenKey(token); redisCache.deleteObject(userKey); } //在原有代码上添加下面的代码 if (!soloLogin && StringUtils.isNotNull(userId)) { String userIdKey = getUserIdKey(userId); redisCache.deleteObject(userIdKey); } } /** * 刷新令牌有效期 * * @param loginUser 登录信息 */ public void refreshToken(LoginUser loginUser) { loginUser.setLoginTime(System.currentTimeMillis()); loginUser.setExpireTime(loginUser.getLoginTime() + expireTime * MILLIS_MINUTE); // 根据uuid将loginUser缓存 String userKey = getTokenKey(loginUser.getToken()); redisCache.setCacheObject(userKey, loginUser, expireTime, TimeUnit.MINUTES); //在原有代码上添加下面的代码 if (!soloLogin) { // 缓存用户唯一标识,防止同一帐号,同时登录 String userIdKey = getUserIdKey(loginUser.getUser().getUserId()); redisCache.setCacheObject(userIdKey, userKey, expireTime, TimeUnit.MINUTES); } } //添加下面的代码 private String getUserIdKey(Long userId) { return Constants.LOGIN_USERID_KEY + userId; }
4、在com.zhdj.framework.security.handle.LogoutSuccessHandlerImpl.java中,清除缓存方法添加用户编号。
// 删除用户缓存记录 // 在原代码参数中添加用户编号:loginUser.getUser().getUserId() tokenService.delLoginUser(loginUser.getToken(), loginUser.getUser().getUserId());
5、在com.zhdj.framework.web.service.SysLoginService.java中,验证如果用户不允许多终端同时登录,清除缓存信息。(我这里是关闭了验证码)
// 是否允许账户多终端同时登录(true允许 false不允许) @Value("${token.soloLogin}") private boolean soloLogin; /** * 登录验证 * * @param username 用户名 * @param password 密码 * @param code 验证码 * @param uuid 唯一标识 * @return 结果 */ public String login(String username, String password, String code, String uuid) { // String verifyKey = Constants.CAPTCHA_CODE_KEY + uuid; // String captcha = redisCache.getCacheObject(verifyKey); // redisCache.deleteObject(verifyKey); // if (captcha == null) { // AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.jcaptcha.expire"))); // throw new CaptchaExpireException(); // } //去掉验证码验证 // if (!code.equalsIgnoreCase(captcha)) { // AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.jcaptcha.error"))); // throw new CaptchaException(); // } // 用户验证 Authentication authentication = null; try { // 该方法会去调用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 CustomException(e.getMessage()); } } AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success"))); LoginUser loginUser = (LoginUser) authentication.getPrincipal(); recordLoginInfo(loginUser.getUser()); // 添加到这里 // 判断是否允许账户多终端同时登录 if (!soloLogin) { // 如果用户不允许多终端同时登录,清除缓存信息 String userIdKey = Constants.LOGIN_USERID_KEY + loginUser.getUser().getUserId(); String userKey = redisCache.getCacheObject(userIdKey); if (StringUtils.isNotEmpty(userKey)) { redisCache.deleteObject(userIdKey); redisCache.deleteObject(userKey); } } // 生成token return tokenService.createToken(loginUser); }