首页 新闻 会员 周边 捐助

redis实现手机号短信登录,优化成JWT 登录认证(用户登录时生成jwttoken) + Redis 自动续期,还能怎么优化呢? 进一步优化:使用双token嘛?再加上rabbitmq?

0
悬赏园豆:200 [待解决问题]

@Override
public Result login(LoginFormDTO loginForm, HttpSession session) {
// 1.校验手机号
String phone = loginForm.getPhone();
if (RegexUtils.isPhoneInvalid(loginForm.getPhone()))
return Result.fail("手机号格式错误");
// 2.校验验证码,从session中获取
//2.1 改进 从redis中获取验证码并校验
String cacheCode = stringRedisTemplate.opsForValue().get(LOGIN_CODE_KEY + phone);
String code = loginForm.getCode();
if (cacheCode == null || !cacheCode.equals(code)) {
// 不一致,报错
return Result.fail("验证码错误");
}
//4一致,根据手机号查询用户, 并且不抛出异常 false
LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(User::getPhone, loginForm.getPhone());
User user = this.getOne(wrapper, false);
//5.判断用户是否存在,手机号注册
if (user == null) {
// 6没有查询到用户,则注册新用户
user = createUserWithPhone(loginForm.getPhone());
}
// TODO 新增 6.生成JWT
Map<String, Object> claims = new HashMap<>();
// 用户ID
claims.put(JwtClaimsConstant.USER_ID, user.getId());
// 确保密钥是 byte[] 类型
String secretKey = jwtProperties.getUserSecretKey();
byte[] keyBytes = secretKey.getBytes(StandardCharsets.UTF_8); // 推荐指定编码
// 生成 Token
String jwttoken = JWTUtil.createToken(claims, keyBytes);

    // 7.2.将User对象转为HashMap存储
    UserDTO userDTO = BeanUtil.copyProperties(user, UserDTO.class);
    Map<String, Object> userMap = BeanUtil.beanToMap(userDTO, new HashMap<>(),   //beanToMap方法执行了对象到Map的转换
            CopyOptions.create()
                    .setIgnoreNullValue(true)   //BeanUtil在转换过程中忽略所有null值的属性
                    .setFieldValueEditor((fieldName, fieldValue) -> fieldValue.toString()));  //对于每个字段值,它简单地调用toString()方法,将字段值转换为字符串。
    // 7.3.存储
    String tokenKey = LOGIN_USER_KEY + userDTO.getId();
    // 7.4.将jwttoken存入userMap中
    userMap.put("jwttoken",jwttoken);
    stringRedisTemplate.opsForHash().putAll(tokenKey, userMap);
    // 7.4.设置token有效期
    stringRedisTemplate.expire(tokenKey, LOGIN_USER_TTL, TimeUnit.MINUTES);
    // 8.返回token
    return Result.ok(jwttoken);
}

private User createUserWithPhone(String phone) {
    // 1.创建用户对象
    User user = new User();
    user.setNickName(USER_NICK_NAME_PREFIX + RandomUtil.randomString(10));
    user.setPhone(phone);
    //2.保存用户
    save(user);
    return user;
}
浮世三千皆过客的主页 浮世三千皆过客 | 初学一级 | 园豆:2
提问于:2025-03-06 21:16
< >
分享
所有回答(1)
0

可以再设置一个refresh_token,该token过期时间较长,仅用来获取新token,不做其他用途。
首次请求返回token和refresh_token,当请求反馈状态是token过期时,使用refresh_token请求新的token和refresh_token,然后继续未完成的请求。
当refresh_token过期时,则重新登录。

CenterLour | 园豆:402 (菜鸟二级) | 2025-03-20 15:44
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册