获取jwt登录token中id三种应用方式

JWT三种应用方式从Token获取登录id

1、定义JWT工具类

​ 里面有个解析的方法

package com.qfedu.common.utils;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;

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

/**
 * jwt工具类
 */
public class JwtUtils {
    // 密钥
    private final static String secret = "123456789qwertyui";

    /**
     * 生成jwt
     *
     * @param claims
     * @return
     */
    public static String createJwt(Map<String, Object> claims) {

        // 签名算法,表示sha256
        SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;

        //构造jwt
        JwtBuilder builder = Jwts.builder()//.setHeaderParam("type","jwt") // 设置头
                .setClaims(claims) // 设置载荷
                .setExpiration(new Date(System.currentTimeMillis() + 180000000)) // 设置过期时间
                .signWith(signatureAlgorithm, secret); // 使用指定算法设置签名
        //生成jwt
        return builder.compact();
    }

    /**
     * 解析,如果不符合,报异常
     *
     * @param jsonWebToken
     * @return
     */
    public static Claims parseJWT(String jsonWebToken) {
        try {
            Claims claims = Jwts.parser()
                    .setSigningKey(secret)
                    .parseClaimsJws(jsonWebToken).getBody();
            return claims;
        } catch (Exception ex) {
            throw new RuntimeException(ex.getMessage());
        }
    }
}

​ 每次使用都需要调这个方法

// 从请求头里获取Token 这个key不固定需前端一样
	String jwt = request.getHeader("Token");
	Claims claims = JwtUtils.parseJWT(jwt);
	Object uid = claims.get("uid");

​ 以这个方法来说有点麻烦每次都需要获取头部token,再去解析

​ 重点来了,为什么不去尝试直接再去写个工具类,直接解析好呢

​ 直接展示代码

2、封装工具类

package com.qfedu.common.utils;

import io.jsonwebtoken.Claims;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;

/**
 * --- 天道酬勤 ---
 *
 * @author Xiaoze
 * @date 2024/8/20
 * @desc
 */
public class TokenUtils {
    public static Integer getUidFromToken() {
        // 动态获取 HttpServletRequest 对象
        ServletRequestAttributes attributes=(ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request= attributes.getRequest();
        String token = request.getHeader("Token");
        if(token == null || token.isEmpty()){
            throw new RuntimeException("token不存在");
        }
        Claims claims = JwtUtils.parseJWT(token);
        Object uid = claims.get("uid");
        return Integer.valueOf(uid.toString());

    }
}

​ 最最最重要的一种方式来了,我这种方式是写在登录拦截器中没错没错就是你想的那种方案

​ 将解析出来的id储存到ThreadLocal中

package com.qfedu.common.interceptor;

import com.qfedu.common.annotation.NoLoginCheck;
import com.qfedu.common.ec.NoLoginException;
import com.qfedu.common.utils.JwtUtils;
import com.qfedu.common.utils.UserUtils;
import io.jsonwebtoken.Claims;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;

/**
 * --- 天道酬勤 ---
 *
 * @author Xiaoze
 * @date 2024/8/19
 * @desc 登录前置拦截器
 */
@Component
public class LoginInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        // 判断访问的控制器的方法有没有使用指定的注解 (NoLoginCheck)
        if(handler instanceof HandlerMethod){
            HandlerMethod handlerMethod = (HandlerMethod) handler;
            Method method = handlerMethod.getMethod();
            // 判断方法是否使用了指定的注解
            boolean ret = handlerMethod.hasMethodAnnotation(NoLoginCheck.class);
            // 说明不需要进行登录状态的判断,直接放行
            if(ret){
                return true;
            }
            String token = request.getHeader("Token");
            if(token == null || "".equals(token)){
                throw new NoLoginException(50008,"无效令牌,请重新登录");
            }

            try {
                Claims claims = JwtUtils.parseJWT(token);
                Object uid = claims.get("uid");
                UserUtils.setId(Integer.valueOf(uid.toString()));
            } catch (Exception e) {
                throw new NoLoginException(50008,"无效令牌,请重新登录");
            }
        }


        return true;
    }
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        // 删除用户id
        UserUtils.removeId();
    }
}

在定义一个工具类

package com.qfedu.common.utils;

/**
 * --- 天道酬勤 ---
 *
 * @author Xiaoze
 * @date 2024/8/20
 * @desc  获取token uid第三种方式
 */
public class UserUtils {
    private static ThreadLocal<Integer> threadLocal = new ThreadLocal<>();
    public static void setId(Integer uid) {
        threadLocal.set(uid);
    }
    public static Integer getId() {
        return threadLocal.get();
    }
    public static void removeId() {
        threadLocal.remove();
    }
}

最后调用

Integer uid = UserUtils.getId();

虽然最后一种方法比前两种方法代码都多,但是这种在工作环境中属于比较装的方式,看不出自己是小白

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值