IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 开发测试 -> 加密解密JwtToken过滤器校验 -> 正文阅读

[开发测试]加密解密JwtToken过滤器校验

需求: 原接口返回的直接是用户信息json串 现在要改成jwt进行加密 获取信息接口放行 其他接口拦截校验jwtToken是否有效

jwtTokenUtil

package com.hzt.intellect.utils;

import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;

import java.nio.charset.StandardCharsets;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

public class JwtUtil {

    /**
     * 生成jwt
     * 使用Hs256算法, 私匙使用固定JWT_SEC秘钥
     *
     * @param jwtSec    jwt秘钥 此秘钥一定要保留好在服务端, 不能暴露出去, 否则sign就可以被伪造, 如果对接多个客户端建议改造成多个
     * @param ttlMillis jwt过期时间(毫秒)
     * @param userInfo  用户名 可根据需要传递的信息添加更多, 因为浏览器get传参url限制,不建议放置过多的参数
     * @return
     */
    public static String createJWT(String jwtSec, long ttlMillis, String userInfo) {
        JSONObject jsonObject = JSONUtil.parseObj(userInfo);
        if (!jsonObject.getBool("success")) {
            return userInfo;
        }
        // 指定签名的时候使用的签名算法,也就是header那部分
        SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;

        // 生成JWT的时间
        long nowMillis = System.currentTimeMillis();
        Date now = new Date(nowMillis);

        // 创建payload的私有声明(根据特定的业务需要添加)
//        Map<String, Object> claims = new HashMap<String, Object>();
//        claims.put("userInfo", userInfo);

        // 添加payload声明
        // 设置jwt的body
        JwtBuilder builder = Jwts.builder()
                // 如果有私有声明,一定要先设置这个自己创建的私有的声明,这个是给builder的claim赋值,一旦写在标准的声明赋值之后,就是覆盖了那些标准的声明的
//                .setClaims(claims)
                // 设置jti(JWT ID):是JWT的唯一标识,根据业务需要,这个可以设置为一个不重复的值,主要用来作为一次性token,从而回避重放攻击。
                .setId(UUID.randomUUID().toString())
                // iat: jwt的签发时间
                .setIssuedAt(now)
                // 代表这个JWT的主体,即它的所有人,这个是一个json格式的字符串
                .setSubject(userInfo)
                // 设置签名使用的签名算法和签名使用的秘钥
                .signWith(signatureAlgorithm, jwtSec.getBytes(StandardCharsets.UTF_8));
        if (ttlMillis >= 0) {
            long expMillis = nowMillis + ttlMillis;
            Date exp = new Date(expMillis);
            // 设置过期时间
            builder.setExpiration(exp);
        }
        jsonObject.set("token", builder.compact());
        return JSONUtil.toJsonStr(jsonObject);
    }


    /**
     * Token的解密
     *
     * @param jwtSec jwt秘钥 此秘钥一定要保留好在服务端, 不能暴露出去, 否则sign就可以被伪造, 如果对接多个客户端建议改造成多个
     * @param token  加密后的token
     * @return
     */
    public static Claims parseJWT(String jwtSec, String token) {
        // 得到DefaultJwtParser
        Claims claims = Jwts.parser()
                // 设置签名的秘钥
                .setSigningKey(jwtSec.getBytes(StandardCharsets.UTF_8))
                // 设置需要解析的jwt
                .parseClaimsJws(token).getBody();
        return claims;
    }
}

过滤器LindTokenAuthenticationFilter

package com.hzt.intellect.filter;

import cn.hutool.core.util.URLUtil;
import cn.hutool.http.ContentType;
import cn.hutool.json.JSONUtil;
import com.hzt.intellect.utils.JwtUtil;
import com.risen.base.frame.constant.ResultEnum;
import com.risen.base.frame.model.Result;
import io.jsonwebtoken.ExpiredJwtException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;
import org.thymeleaf.util.StringUtils;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * token filter bean.
 */
@Slf4j
@Component
public class LindTokenAuthenticationFilter extends OncePerRequestFilter {

    @Value("${jwt.jwtSec}")
    private String jwtSec;
    @Value("${jwt.tokenName}")
    private String tokenName;
    @Value("${jwt.releasePath}")
    private String releasePath;

    @Override
    protected void doFilterInternal(
            HttpServletRequest request,
            HttpServletResponse response,
            FilterChain filterChain) throws ServletException, IOException {
        List<String> releasePathList = new ArrayList<>(Arrays.asList(releasePath.split(",")));
        //获取路径
        String path = URLUtil.getPath(request.getRequestURI());
        //获取接口路径,根据第二个的位置,截取 字符串
        String result = path.substring(path.indexOf("/", path.indexOf("/") + 1));
        if (releasePathList.contains(result)) {
            filterChain.doFilter(request, response);
            return;
        }
        String token = request.getHeader(tokenName);
        if (StringUtils.isEmpty(token)) {
            token = request.getParameter(tokenName);
        }
        if (StringUtils.isEmpty(token)) {
            response.setStatus(501);
            response.setContentType(ContentType.JSON.getValue());
            Result<String> resultMsg = Result.buildResult(ResultEnum.PERMISSION_NO_ACCESS, "token不能为空");
            response.getWriter().write(JSONUtil.toJsonStr(resultMsg));
            return;
        }

        try {
            JwtUtil.parseJWT(jwtSec, token);
        } catch (ExpiredJwtException e) {
            log.error("jwtToken过期:{}", token);
            response.setStatus(501);
            response.setContentType(ContentType.JSON.getValue());
            Result<String> resultMsg = Result.buildResult(ResultEnum.TOKEN_ILLEGAL, "token过期");
            response.getWriter().write(JSONUtil.toJsonStr(resultMsg));
            return;
        } catch (Exception e) {
            log.error("jwtToken解析异常token:{}, 异常原因:{}", token, e);
            response.setStatus(501);
            response.setContentType(ContentType.JSON.getValue());
            Result<String> resultMsg = Result.buildResult(ResultEnum.AUTHENTICATION_NO_SUCCESS, "token异常");
            response.getWriter().write(JSONUtil.toJsonStr(resultMsg));
            return;
        }
        filterChain.doFilter(request, response);
    }

}

配置
在这里插入图片描述

  开发测试 最新文章
pytest系列——allure之生成测试报告(Wind
某大厂软件测试岗一面笔试题+二面问答题面试
iperf 学习笔记
关于Python中使用selenium八大定位方法
【软件测试】为什么提升不了?8年测试总结再
软件测试复习
PHP笔记-Smarty模板引擎的使用
C++Test使用入门
【Java】单元测试
Net core 3.x 获取客户端地址
上一篇文章      下一篇文章      查看所有文章
加:2022-03-08 22:52:24  更:2022-03-08 22:53:01 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/18 2:38:30-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码