拦截器 jwt Threadlocal

目录

一、登录认证问题

二、拦截器

三、ThreadLocal

3.1 使用场景

3.2 使用



一、登录认证问题

在未登录的情况下,不应该访问到其他资源,而是应该回到登录页面

使用jwt令牌技术(令牌就是一段字符串)

Header( ), 记录令牌类型和签名算法等
PayLoad( 载荷 ), 携带自定义的信息
Signature( 签名 ), 对头部和 载荷 进行加密计算得来

使用:

1、首先需要在pom文件中引入jwt令牌的坐标

2、调用api进行使用(将来使用的时候都是使用已经提供好的工具类)

public class JwtUtil {

    private static long tokenExpiration = 60 * 60 * 1000L; //一个小时
    private static SecretKey tokenSignKey = Keys.hmacShaKeyFor("zyx5201314zyx5211314zyx520521zyx".getBytes());

    public static String createToken(Long userId, String username) {
        String token = Jwts.builder().
                setSubject("USER_INFO").
                setExpiration(new Date(System.currentTimeMillis() + tokenExpiration)).
                claim("userId", userId).
                claim("username", username).
                signWith(tokenSignKey, SignatureAlgorithm.HS256).
                compact();
        return token;
    }

    // 校验JWT合法性的逻辑
    public static Claims parseToken(String token) {

        if(token == null){
            throw new LeaseException(ResultCodeEnum.ADMIN_LOGIN_AUTH);
        }
        try{
            JwtParser jwtParser = Jwts.parserBuilder().setSigningKey(tokenSignKey).build();
            Claims claims = jwtParser.parseClaimsJws(token).getBody();
            return claims;

        }catch (ExpiredJwtException e){ //token过期
            throw new LeaseException(ResultCodeEnum.TOKEN_EXPIRED);
        }catch (JwtException e){ //异常的父类
            throw new LeaseException(ResultCodeEnum.TOKEN_INVALID); //token非法
        }
    }
}

以后在登录成功的时候生成一个jwt令牌token

实例:

将来我们在调用其它接口的时候,需要验证jwt令牌token的合法性(多个接口都需要验证,我们可以使用拦截器完成校验)

二、拦截器

1、首先定义一个类实现HandlerInterceptor接口并且重写preHandle方法

实例:我们在方法里面校验令牌

2、写一个web配置类实现webMvcConfigurer接口,并且在addInterceptors方法(添加拦截器)里面通过@Autowired注解获取并把我们刚刚编写的拦截器给它注册进去

实例(登录和注册的接口不进行拦截):

三、ThreadLocal

3.1 使用场景

在每个线程内需要保存全局变量(例如在拦截器中获取用户信息),可以让不同方法直接使用,避免参数传递的麻烦。

1、用来存储数据:set()和get()

2、使用ThreadLocal存储的数据是线程安全的

3、用完使用remove方法进行释放

3.2 使用

使用threadlocal工具类

public class ThreadLocalUtil {
    //提供ThreadLocal对象,
    private static final ThreadLocal THREAD_LOCAL = new ThreadLocal();

    //根据键获取值
    public static <T> T get(){
        return (T) THREAD_LOCAL.get();
    }
	
    //存储键值对
    public static void set(Object value){
        THREAD_LOCAL.set(value);
    }


    //清除ThreadLocal 防止内存泄漏
    public static void remove(){
        THREAD_LOCAL.remove();
    }
}

在拦截器中存储用户的数据

在接口中获取ThreadLocal存储的数据

ThreadLocal的清除(防止内存泄漏)

场所:请求发过来的时候,我们解析它携带的token并且把它存到ThreadLocal里面,接下来这个请求放行了之后,在响应完成之后这一次请求结束了就不再使用了,就可以把它移除掉

我们可以在拦截器LoginInterceptor类中的afterCompletion方法中清空ThreadLocal中的数据

 // 清理线程池
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        LoginUserHolder.clear();
    }

  • 43
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值