写下大致方案:
1、登录后用Jwt生成token
2、token信息存储到redis中
3、同时token和设备信息存cookie中
4、判断设备信息不一致redis失效原来的token,产生新token可互踢
拦截器示例代码为不允许多设备登录
try {
String redisToken = stringRedisTemplate.opsForValue().get(Constents.Redis.LOGIN_ID_PREFIX + userBase.getLoginId());
if (StringHelper.isEmpty(redisToken)) {
result.setErrorNo(-999);
result.setErrorMsg("您还未登录");
return result;
}
ResultVo vo = userService.findByLongId(userBase.getLoginId());
Map data = vo.getData();
if(data.getInt("is_sso") == 0) {
// 1不限制 0限制
String cookieToken = CookieHelper.getCookieValue(request, Constents.Session.COOKIE_LOGIN_TOKEN);
String saveCookieToken = (String) request.getAttribute("saveCookieToken");
log.info("singlePointCheck cookieToken:{} redisToken:{} cookieToken:{}", saveCookieToken, redisToken, cookieToken);
if (StringHelper.isEmpty(saveCookieToken) && !redisToken.equals(cookieToken)) {
result.setErrorNo(9);
result.setErrorMsg("您的账号已在它处登录");
} else {
result.setErrorNo(0);
stringRedisTemplate.expire(Constents.Redis.LOGIN_ID_PREFIX + user.getLoginId(), Constents.Redis.LOGIN_EXPIRED_TIME, TimeUnit.MINUTES);
}
} else {
result.setErrorNo(0);
stringRedisTemplate.expire(Constents.Redis.LOGIN_ID_PREFIX + userBase.getLoginId(), Constents.Redis.LOGIN_EXPIRED_TIME, TimeUnit.MINUTES);
}
} catch (Exception e) {
result.setErrorNo(-1);
result.setErrorMsg(e.getMessage());
log.error("登录失败 {}", e);
}