工具类:JWT(0.12.3)

依赖

    <!--     创建、解析 和 验证JSON Web Tokens (JWT)-->
        <dependency>
            <groupId>io.jsonwebtoken</groupId>
            <artifactId>jjwt</artifactId>
            <version>0.12.3</version>
        </dependency>

application.yml文件配置

jwt:
    # 设置jwt签名加密时使用的秘钥   HMAC-SHA算法32字节
    admin-secret-key: 1ost-very-long-and-secure-secret-key-32-bytes
    # 设置jwt过期时间
    admin-ttl: 7200000
    # 设置前端传递过来的令牌名称
    admin-token-name: token

JwtProperties.java

package com.nnutc.system.config;

@Configuration
@ConfigurationProperties(prefix = "jwt")
@Component // 或者使用 @Configuration(proxyBeanMethods = false) 并依赖注入到需要的地方
public class JwtProperties {

    private String adminSecretKey;
    private long adminTtl;
    private String adminTokenName;

    // Getters and Setters
    public String getAdminSecretKey() {
        return adminSecretKey;
    }

    public void setAdminSecretKey(String adminSecretKey) {
        this.adminSecretKey = adminSecretKey;
    }

    public long getAdminTtl() {
        return adminTtl;
    }

    public void setAdminTtl(long adminTtl) {
        this.adminTtl = adminTtl;
    }

    public String getAdminTokenName() {
        return adminTokenName;
    }

    public void setAdminTokenName(String adminTokenName) {
        this.adminTokenName = adminTokenName;
    }
}

JwtUtil.java

package com.nnutc.common.utils;

@Component
public class JwtUtil {
    String secret = "1ost-very-long-and-secure-secret-key-32-bytes";
    int ttl = 7200000;

    /**
     * 初始化负载内数据
     * @param username 用户名
     * @return 负载集合
     */
    private Map<String,Object> initClaims(String username){
        Map<String, Object> claims = new HashMap<>();
        //"iss" (Issuer): 代表 JWT 的签发者。在这个字段中填入一个字符串,表示该 JWT 是由谁签发的。例如,可以填入你的应用程序的名称或标识符。
        claims.put("iss","olTool");
        //"sub" (Subject): 代表 JWT 的主题,即该 JWT 所面向的用户。可以是用户的唯一标识符或者其他相关信息。
        claims.put("sub",username);
        //"exp" (Expiration Time): 代表 JWT 的过期时间。通常以 UNIX 时间戳表示,表示在这个时间之后该 JWT 将会过期。建议设定一个未来的时间点以保证 JWT 的有效性,比如一个小时、一天、一个月后的时间。
        claims.put("exp",generatorExpirationDate());
        //"aud" (Audience): 代表 JWT 的接收者。这个字段可以填入该 JWT 预期的接收者,可以是单个用户、一组用户、或者某个服务。
        claims.put("aud","internal use");
        //"iat" (Issued At): 代表 JWT 的签发时间。同样使用 UNIX 时间戳表示。
        claims.put("iat",new Date());
        //"jti" (JWT ID): JWT 的唯一标识符。这个字段可以用来标识 JWT 的唯一性,避免重放攻击等问题。
        claims.put("jti", UUID.randomUUID().toString());
        //"nbf" (Not Before): 代表 JWT 的生效时间。在这个时间之前 JWT 不会生效,通常也是一个 UNIX 时间戳。我这里不填,没这个需求
        return claims;
    }

    /**
     * 根据负载生成JWT token
     * @param claims 负载
     * @return token
     */
    public String  generatorToken(Map<String,Object> claims){
        //指定加密算法
        SecureDigestAlgorithm<SecretKey, SecretKey> algorithm = Jwts.SIG.HS256;
        //密钥实例
        SecretKey key = Keys.hmacShaKeyFor(secret.getBytes());
        return Jwts.builder()
                .claims(claims)
                .signWith(key,algorithm)
                .compact();
    }



    /**
     * 从Token中获取负载中的Claims
     * @param token token
     * @return 负载
     */
    public Claims getPayloadFromToken(String token) {
        //密钥实例
        SecretKey key = Keys.hmacShaKeyFor(secret.getBytes());
        return Jwts.parser()
                .verifyWith(key)
                .build()
                .parseSignedClaims(token)
                .getPayload();
    }

    /**
     * 从Token中获取用户名
     * @param token token
     * @return 用户名
     */
    public String getUserNameFromToken(String token){
        String username;
        try
        {
            username = getPayloadFromToken(token).getSubject();
        }catch (Exception e){
            username = null;
        }
        return username;
    }



    /**
     * 生成失效时间,以秒为单位
     *
     * @return 预计失效时间
     */
    private Date generatorExpirationDate()
    {
        //预计失效时间为:token生成时间+预设期间
        return new Date(System.currentTimeMillis() + ttl);
    }
    /**
     * 验证token是否有效
     * @param token 需要被验证的token
     * @param userDetails true/false
     * @return
     */
//    public boolean validateToken(String token,UserDetails userDetails){
//        return getUserNameFromToken(token).equals(userDetails.getUsername()) && !isTokenExpired(token);
//    }

    /**
     * 判断token是否有过期
     * @param token 需要被验证的token
     * @return true/false
     */
    private boolean isTokenExpired(String token)
    {
        //判断预设时间是否在当前时间之前,如果在当前时间之前,就表示过期了,会返回true
        return getExpiredDateFromToken(token).before(new Date());
    }

    /**
     * 从token中获取预设的过期时间
     * @param token token
     * @return 预设的过期时间
     */
    private Date getExpiredDateFromToken(String token)
    {
        return getPayloadFromToken(token).getExpiration();
    }

    /**
     * 判断token是否可以被刷新
     * @param token 需要被验证的token
     * @return true/false
     */
    public boolean canRefresh(String token){
        return !isTokenExpired(token);
    }

    /**
     * 刷新token
     * @param token 需要被刷新的token
     * @return 刷新后的token
     */
    public String refreshToken(String token){
        Claims claims = getPayloadFromToken(token);
        Map<String, Object> initClaims = initClaims(claims.getSubject());
        initClaims.put("iat",new Date());
        return generatorToken(initClaims);
    }
}

controller类

String jsonString = JSON.toJSONString(customUserDetails);
        Map<String, Object> claims = new HashMap<>();
        claims.put("customUserDetails", jsonString); // 你可以添加其他信息

String token = JwtUtil.createJWT(
                jwtProperties.getAdminSecretKey(),
                jwtProperties.getAdminTtl(),
                claims);

过滤器

package com.nnutc.system.filter;


@Component
public class JwtAuthenticationTokenFilter extends OncePerRequestFilter {

    @Autowired
    private JwtProperties jwtProperties;

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
            throws ServletException, IOException {
        String uri = request.getRequestURI();
        if (uri.equals("/admin/system/index/login")) {//直接放行
            filterChain.doFilter(request, response);
            return;
        }
        String token = request.getHeader("Authorization");

        if (!StringUtils.hasText(token)) {//header中没有token
            throw new RuntimeException("Token为空");
        }
        try{
            Jws<Claims> claims = JwtUtil.parseJWT(token, jwtProperties.getAdminSecretKey());

            filterChain.doFilter(request, response);//放行
        }catch (Exception e){
            throw new RuntimeException(e);

        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值