JWT token

JWT Token是一种流行的认证和授权机制,它通过JSON Web Tokens来传递信息。本文将介绍JWT的构成、工作原理以及如何在应用程序中实现JWT,包括生成、验证和管理JWT Token的过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.wpdata.management.param.LoginInfoParam;
import io.jsonwebtoken.*;
import liquibase.pro.packaged.J;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.UUID;

/**
 * JWT工具
 */
public class JWTUtils {

    /**
     * 服务器的key。用于做加解密的key数据。 如果可以使用客户端生成的key。当前定义的常亮可以不使用。
     */
    private static final String JWT_SECERT = "test_jwt_secert";

    private static final ObjectMapper MAPPER = new ObjectMapper();

    /**
     * Token过期
     */
    public static final int JWT_ERRCODE_EXPIRE = 1005;

    /**
     * 验证不通过
     */
    public static final int JWT_ERRCODE_FAIL = 1006;

    public static SecretKey generalKey() {
        try {
            // byte[] encodedKey = Base64.decode(JWT_SECERT);
            // 不管哪种方式最终得到一个byte[]类型的key就行
            byte[] encodedKey = JWT_SECERT.getBytes("UTF-8");
            SecretKey key = new SecretKeySpec(encodedKey, 0, encodedKey.length, "AES");
            return key;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 签发JWT,创建token的方法。
     *
     * @param id        jwt的唯一身份标识,主要用来作为一次性token,从而回避重放攻击。
     * @param iss       jwt签发者
     * @param subject   jwt所面向的用户。payload中记录的public claims。当前环境中就是用户的登录名。
     * @param ttlMillis 有效期,单位毫秒
     * @return token, token是一次性的。是为一个用户的有效登录周期准备的一个token。用户退出或超时,token失效。
     * @throws Exception
     */
    public static String createJWT(String id, String iss, String subject, long ttlMillis) {
        // 加密算法
        SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;
        // 当前时间。
        long nowMillis = System.currentTimeMillis();
        // 当前时间的日期对象。
        Date now = new Date(nowMillis);
        SecretKey secretKey = generalKey();
        // 创建JWT的构建器。 就是使用指定的信息和加密算法,生成Token的工具。
        JwtBuilder builder = Jwts.builder()
                // 设置身份标志。就是一个客户端的唯一标记。 如:可以使用用户的主键,客户端的IP,服务器生成的随机数据。
                .setId(id)
                .setIssuer(iss)
                .setSubject(subject)
                .claim("uuid", UUID.randomUUID().toString())
                // token生成的时间。
                .setIssuedAt(now)
                // 设定密匙和算法
                .signWith(signatureAlgorithm, secretKey);
        if (ttlMillis >= 0) {
            long expMillis = nowMillis + ttlMillis;
            // token的失效时间。
            Date expDate = new Date(expMillis);
            builder.setExpiration(expDate);
        }
        // 生成token
        return builder.compact();
    }

    /**
     * 验证JWT
     *
     * @param jwtStr
     * @return
     */
    public static JWTResult validateJWT(String jwtStr) {
        JWTResult checkResult = new JWTResult();
        Claims claims = null;
        try {
            claims = parseJWT(jwtStr);
            checkResult.setSuccess(true);
            checkResult.setClaims(claims);
        } catch (ExpiredJwtException e) { // token超时
            checkResult.setErrCode(JWT_ERRCODE_EXPIRE);
            checkResult.setSuccess(false);
        } catch (SignatureException e) { // 校验失败
            checkResult.setErrCode(JWT_ERRCODE_FAIL);
            checkResult.setSuccess(false);
        } catch (Exception e) {
            checkResult.setErrCode(JWT_ERRCODE_FAIL);
            checkResult.setSuccess(false);
        }
        return checkResult;
    }

    /**
     * 解析JWT字符串
     *
     * @param jwt 就是服务器为客户端生成的签名数据,就是token。
     * @return
     * @throws Exception
     */
    public static Claims parseJWT(String jwt) throws Exception {
        SecretKey secretKey = generalKey();
        return Jwts.parser()
                .setSigningKey(secretKey)
                .parseClaimsJws(jwt)
                .getBody(); // getBody获取的就是token中记录的payload数据。就是payload中保存的所有的claims。
    }

    /**
     * 生成subject信息
     *
     * @param subObj - 要转换的对象。
     * @return java对象->JSON字符串出错时返回null
     */
    public static String generalSubject(Object subObj) {
        try {
            return MAPPER.writeValueAsString(subObj);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
            return null;
        }
    }

    public static LoginInfoParam getInfoFromToken(String token) throws Exception {
        Claims claims = parseJWT(token);
        String loginInfo = (String) claims.get("sub");
        com.alibaba.fastjson.JSONObject jsonObject = com.alibaba.fastjson.JSONObject.parseObject(loginInfo);
        String loginInfoParam = jsonObject.getString("loginInfoParam");
        LoginInfoParam loginInfoParam1 = JSON.parseObject(loginInfoParam, LoginInfoParam.class);
        return loginInfoParam1;
    }


    public static LoginInfoParam getLoginInfo() {
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        String token = request.getHeader("Authorization");

        try {
            Claims claims = parseJWT(token);
            String loginInfo = (String) claims.get("sub");
            JSONObject map = JSONObject.parseObject(loginInfo).getJSONObject("map");
            LoginInfoParam result = map.getObject("user", LoginInfoParam.class);
            return result;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值