Jwt前后端分离中的使用

在springboot项目中加入如下依赖

<dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt</artifactId>
    <version>0.9.1</version>
</dependency>
<dependency>
    <groupId>com.auth0</groupId>
    <artifactId>java-jwt</artifactId>
    <version>3.19.1</version>
</dependency>

 编写Jwt工具类JwtUtil

public class JwtUtil {
    /**
     * token 过期时间, 单位: 秒. 这个值表示 30 天
     */
    private static final long TOKEN_EXPIRED_TIME = 30 * 24 * 60 * 60;

    public static final String jwtId = "tokenId";

    /**
     * jwt 加密解密密钥(可自行填写)
     */
    private static final String JWT_SECRET = "1234567890";
    /**
     * 用户登录成功后生成jwt
     * 使用Hs256算法
     * 三部分组成 头部+荷载+签证信息
     * @param ttlMillis jwt过期时间
     * @return
     */
    public static String createJwt(long ttlMillis, Integer id,String username){
        // header部分,jwt已经封装好了
        SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;
        // jwt生成时间 当前时间
        long nowMillis = System.currentTimeMillis();
        Date date = new Date(nowMillis);

        // payload 荷载部分(存放有效信息的地方,包含标准中注册的声明、公共声明、私有声明)
        // 创建私有声明
        Map<String,Object> claims = new HashMap<>();
        claims.put("id", id);
        claims.put("username",username);
        // 为payload添加标准声明和私有声明(new一个JwtBuilder,设置jwt的body)
        JwtBuilder jwtBuilder = Jwts.builder()
                // 先设置自己创建的私有声明,要是写在标准声明后面,会覆盖掉标准声明
                .setClaims(claims)
                // 设置jti(jwt id),主要用来作为一次性token,从而回避重放攻击
                .setId(UUID.randomUUID().toString())
                // 设置iat jwt签发时间
                .setIssuedAt(date)
                // 设置jwt的所有人
                .setSubject(username)
                // 设置签名使用的签名算法和签名使用的秘钥
                .signWith(signatureAlgorithm, JWT_SECRET);
        // 设置jwt的过期时间
        if(ttlMillis>= 0){
            long expMillis = ttlMillis+nowMillis;
            Date expDate = new Date(expMillis);
            jwtBuilder.setExpiration(expDate);
        }
        System.out.println("生成jwt");
        return jwtBuilder.compact();
    }

    /**
     * 验证jwt
     */
    public static Claims verifyJwt(String token) {
        // 签名秘钥(与生成签名的秘钥一样)
        // 得到DefaultJwtParser
        return  Jwts.parser()
                // 设置签名的秘钥
                .setSigningKey(JWT_SECRET)
                // 设置需要解析的jwt
                .parseClaimsJws(token).getBody();

    }
}

编写后端的Jwt拦截器JwtInterceptor

@Component
public class JwtInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, @NotNull HttpServletResponse response, @NotNull Object handler) throws Exception {
        String token = request.getHeader("token");
        String msg = "缺少token";
        if(token ==null){
            response.setContentType("application/json; charset=UTF-8");
            ObjectMapper mapper = new ObjectMapper();
            String result = mapper.writeValueAsString(R.error(401,msg));
            response.getWriter().print(result);
            return false;
        }
        try {
            Claims claims = JwtUtil.verifyJwt(token);
            if (claims!=null){
                return true;
            }
        }catch (SignatureVerificationException e){
            msg= "无效签名";
        }catch (TokenExpiredException e){
            msg= "已过期";
        }catch (AlgorithmMismatchException e){
            msg ="算法不一致";
        }catch (Exception e){
            msg="无效身份信息";
        }
        response.setContentType("application/json; charset=UTF-8");
        ObjectMapper mapper = new ObjectMapper();
        String result = mapper.writeValueAsString(R.error(401,msg));
        response.getWriter().print(result);
        return false;
    }
}

编写Jwt拦截器的配置

@Configuration
public class JwtInterceptorConfig implements WebMvcConfigurer {

    @Autowired
    private JwtInterceptor jwtInterceptor;
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        // 用户拦截器
        registry.addInterceptor(jwtInterceptor)
                // 需要拦截的请求
                .addPathPatterns("/**")
                //需要放行的请求
                .excludePathPatterns("/captcha","/login");
                // 添加swagger-ui的放行路径
//                .excludePathPatterns("/swagger-resources/**", "/webjars/**", "/v2/**", "/swagger-ui.html/**","/doc.html/**");
    }

}

 前端编写

首先是登陆成功将token放到本地保存起来

window.localStorage.setItem("token", resp.token)

 然后是每次发请求带上token

// 请求发生前处理
config.headers = {
    // 每次请求前带上Token
    token: window.localStorage.getItem("token")
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

LeeGaKi

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值