统一处理Token

将业务层的token处理,进行统一处理

如何统一处理?

自定义拦截器类实现HandlerInterceptor接口进行拦截

统一处理token后,业务层如何获取user信息?

本地线程ThreadLocal存储user信息,业务层直接可以从ThreadLocal获取user信息

拦截器的使用

1自定义一个类实现HandleInterceptor接口。


2.实现HandLerInterceptor接口的三个方法:

 -preHandle():在目标方法之前执行,一般用于预处理(在请求进入controller之前处理)

 - postHandle():在目标方法执行之后执行,一般用于后处理 

- afterCompletion():整个请求处理完毕,在视图渲染完毕时回调,一般用于资源的清理或性能的统计

3.在springboot中注册拦截器并使用

ThreadLocal

UserHolder工具类(提供两个方法getUser() getUserId())

ThreadLocal<User> threadLocal=new ThreadLocal<T> (

threadLocal.set();//将数据绑定到当前线程

threadLocal.get();//从当前线程中获取数据

统一处理token实现分析

1.UserHolder工具类(提供两个方法getUser() getUserId())

2.修改拦截器-编写拦截业务逻辑

a.根据request对象获取请求头中的token

b.token如果为空,那么返回401(没有权限访问,需要进行身份验证)

c.token如果不为空,根据token作为key到redis获取用户对象

d.如果用户对象为空,那么返回401

e.如果用户对象不为空,通过UserHoler.setUser()存入ThreadLocal return true;

3.修改controller将token参数删除//之前的代码中直接传入token

4.修改service将token处理代码删除,替换为UserHoler.getUserserId()//之前的代码中直接传入token

 utils

JwtUtils
package com.tanhua.server.utils;

import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

@Component
public class JwtUtils {

    @Value("${tanhua.secret}")
    private String secret;

    /**
     * 生成JWT
     *
     * @return
     */
    public String createJWT(String phone,Long userId) {
        Map<String, Object> claims = new HashMap<String, Object>();
        claims.put("mobile", phone);
        claims.put("id", userId);
        long nowMillis = System.currentTimeMillis();
        Date now = new Date(nowMillis);
        JwtBuilder builder = Jwts.builder()
            .setClaims(claims)
            .setIssuedAt(now)//过期时间 立马过期
            .signWith(SignatureAlgorithm.HS256, secret);
        return builder.compact();
    }
}

interceptor(拦截器)

TokenInterceptor
package com.tanhua.server.interceptor;

import com.tanhua.domain.db.User;
import com.tanhua.server.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * 自定义拦截器
 */
@Component
@Slf4j
public class TokenInterceptor implements HandlerInterceptor {

    @Autowired
    private UserService userService;

    /**
     * 进入controller之前执行此方法
     *
     * @param request
     * @param response
     * @param handler
     * @return
     * @throws Exception
     */
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

        //a.根据request对象获取请求头中token
        String headToken = request.getHeader("Authorization");
        //b.token如果为空直接返回401(用户没有访问权限,需要进行身份认证。)
        if (StringUtils.isEmpty(headToken)) {
            response.setStatus(401);
            return false;
        }
        //c.token如果不为空,根据token作为key到redis中获取用户对象
        User user = userService.getUserByToken(headToken);
        //d.如果用户对象为空,返回401
        if (StringUtils.isEmpty(user)) {
            response.setStatus(401);
            return false;
        }

        //e.如果用户对象不为空,通过UserHoler.setUser()存入ThreadLocal return true;
        UserHolder.setUser(user);
        log.debug("user{}*************拦截执行结束了*************",user.toString());
        return true;
    }
}
WebConfig
package com.tanhua.server.config;

import com.tanhua.server.interceptor.TokenInterceptor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

/**
 * 拦截器配置类 类似于springmvc.xml中拦截器配置
 */
@Configuration
public class WebConfig implements WebMvcConfigurer {

    @Autowired
    private TokenInterceptor tokenInterceptor;

    /**
     *
     * 将自定义拦截器添加spring容器中
     * @param registry
     */
    public void addInterceptors(InterceptorRegistry registry) {
        //哪些请求要拦截 哪些请求放行(登录-登录第一步---获取验证码 登录第二步---注册登录)
        registry.addInterceptor(tokenInterceptor)
                .addPathPatterns("/**")
                .excludePathPatterns("/user/login","/user/loginVerification");
    }
}
UserHolder
package com.tanhua.server.interceptor;

import com.tanhua.domain.db.User;

/**
 * 登陆用户信息持有者
 * 通过ThreadLocal的形式,存储登陆用户的数据
 */
public class UserHolder {

    private static ThreadLocal<User> userThreadLocal = new ThreadLocal<User>();

    /**
     * 向当前线程中存入用户数据
     * @param user
     */
    public static void setUser(User user){
        userThreadLocal.set(user);
    }

    /**
     * 从当前线程中获取用户数据
     * @return
     */
    public static User getUser(){
        return userThreadLocal.get();
    }

    /**
     * 获取登陆用户的id
     * @return
     */
    public static Long getUserId(){
        return userThreadLocal.get().getId();
    }
}

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值