Token机制改造过程中踩坑记录

Token机制改造过程中踩坑记录


上个月为了修改系统的认证方式为Token机制,编码两天,修BUG修了一整周,天天加班到深夜,踩坑无数,终于爬上来了,现记录如下。


问题背景

  1. 系统原有登录认证机制为手机号+验证码登录并保存Cookie,由前端调用CheckLogin接口判断登录信息是否还存在,后端通过Cookie里的userId来关联用户信息;
  2. 此种认证方案在我接手后就提出优化意见,不过由于任务繁多,直到前些日子才抽出时间修改;
  3. 和前端同学一起讨论确定认证方式为Token机制,具体见博文微信公众号用户认证机制升级方案

具体实现

  1. 用户认证登录实现

     /**
      * 用户认证登录接口
      * @param auth
      * @return
      */
     @RequestMapping(method = RequestMethod.POST)
     public BaseResult<UserToken> auth(@RequestBody AuthVO auth, @RequestHeader("timestamp") Long  timestamp) throws Exception {
         //省略前置校验等代码
         //生成UserToken和SecretKey
         String token = MD5.getInstance().getMD5String(UUID.randomUUID().toString());
         while (redisTemplate.opsForValue().get(USER_TOKEN_REDIS_PRE+token) != null){
             token = MD5.getInstance().getMD5String(UUID.randomUUID().toString());
         }
         String secretKey = MD5.getInstance().getMD5String(UUID.randomUUID().toString());
         Long expire = calendar.getTimeInMillis();
    
         UserToken userToken = new UserToken(token,secretKey,expire);
         //更新用户的SecretKey
         member.setSecretKey(secretKey);
         memberService.updateMemberById(member);
    
         //将Token & userId存入Redis
         redisTemplate.opsForValue().set(USER_TOKEN_REDIS_PRE+token,  String.valueOf(member.getId()), 30, TimeUnit.DAYS);
    
         return BaseResultUtils.ok(userToken);
     }
  2. 鉴权注解

    /**
    * 鉴权注解,在Controller的方法上添加该注解表明此方法需要进行登录信息鉴权
    * 未登录返回 401 错误 - 未授权 (Unauthorized)
    * User: za-panyong
    * Date: 2018/5/9
    * Time: 15:27
    */
    @Target(ElementType.METHOD)
    @Retention(RetentionPolicy.RUNTIME)
    public @interface Authorization {
         
    }
  3. RequestBody过滤器

    public class RequestFilter implements Filter {
         
     //线程缓存,保存RequestBody
     public static ThreadLocal<MyRequestBodyReaderWrapper> REQUEST_WRAPPER = new ThreadLocal<>();
    
     @Override
     public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)  throws IOException, ServletException {
         HttpServletRequest servletRequest = (HttpServletRequest) request;
         //如果是GET请求或者请求类型不是application/json,则不需要获取RequestBody
         if (StringUtils.isEmpty(servletRequest.getMethod()) ||  "GET".equalsIgnoreCase(servletRequest.getMethod())
          
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值