需求:用户在客户端A登录,然后又在客户端B登录会将挤下客户端A的登录,也就是不允许用户在不同的客户端登录。

private void redisSaveLoginToken(String userIdMD5, String newToken) {
String redisKey = RedisConstant.REDIS_USER_PREFIX + userIdMD5;
BoundValueOperations<String, String> operations = stringRedisTemplate.boundValueOps(redisKey);
// 获取旧token
String oldToken = operations.get();
// 设置新token
if (StringUtils.isNotBlank(newToken)) {
operations.set(newToken, RedisConstant.REDIS_TOKEN_TTL, TimeUnit.MINUTES);
}
// 传递旧token给redisSaveUserInfo方法
redisSaveUserInfo(newToken, user, remoteAddr, oldToken);
}
private void redisSaveUserInfo(String newToken, User user, String remoteAddr, String oldToken) {
String redisKey = RedisConstant.REDIS_TOKEN_PREFIX + newToken;
UserDto userDto = new UserDto();
BeanUtils.copyProperties(user, userDto);
userDto.setRemoteAddr(remoteAddr);
String userJSON = JacksonUtil.writeValueAsString(userDto);
log.info("[redisSaveUserInfo] userJSON:{}", userJSON);
try {
stringRedisTemplate.opsForValue().set(redisKey, userJSON, RedisConstant.REDIS_TOKEN_TTL, TimeUnit.MINUTES);
} catch (Exception e) {
log.error("[Redis-addOps]" + e.getMessage());
}
// 根据旧token删除Redis旧客户端登录的用户信息(旧token作废),oldToken==null 表示第一次登录
if (StringUtils.isNotBlank(oldToken)) {
log.info("oldToken:{}", oldToken);
String deleteKey = RedisConstant.REDIS_TOKEN_PREFIX + oldToken;
try {
stringRedisTemplate.delete(deleteKey);
} catch (Exception e) {
log.error("[Redis-delOps]" + e.getMessage());
}
}
}
后续补充:上面的方案将用户信息存在Redis 相对占用资源,下面的方案是结合JWT 来做,token 存在客户端,JWT 的非对称加密也会更加安全 (推荐)


1117

被折叠的 条评论
为什么被折叠?



