JSON Web Token (JWT)

JWT是一种开放标准,用于在各方之间安全地传输信息。它由header、payload和signature三部分组成,常用于身份验证。JWT的header包含类型和算法,payload存储用户信息,signature确保数据不可篡改。JWT的优势在于无状态和防篡改,但无法中途废弃和承载过多信息。Java开发者可以使用jjwt或java-jwt库来实现JWT的创建、校验和解析。
摘要由CSDN通过智能技术生成

        JSON Web Token (JWT) 是一种开放标准 ( RFC 7519 ),我们常说的jwt token(令牌),其实就是按照jwt制定的标准生成的字符串令牌。

jwt组成

        jwt由header,playload,signature三部分组成,令牌最终的格式像这样:xxxxx.yyyyy.zzzzz

        header(标头):通常由两部分组成:令牌的类型(JWT)和所使用的签名算法(如HMAC SHA256或RSA),经过Base64Url编码后形成JWT的第一部分,如下图。

{
  "alg": "HS256",
  "typ": "JWT"
}

        playload(有效负载):存放用户自定义的信息,通常会把用户信息和令牌到期时间放在这里,同样是一个json对象,里面的key和value可随意设置,经过Base64Url编码后形成JWT的第二部分,由于部分是没有加密的,建议只存放一些非敏感信息,如下图。

{
  "sub": "1234567890",
  "name": "John Doe",
  "admin": true
}

         signature(签名):使用标头的算法和私钥对第一部分和第二部分进行加密,通过Base64Url编码后形成JWT的第三部分,如下图。

HMACSHA256(
  base64UrlEncode(header) + "." +
  base64UrlEncode(payload),
  secret)

        完整的jwt令牌像这样:eyJhbGciOiJIUzI1NiIsInppcCI6IkRFRiJ9.eNqqVkqtKFCyMjSzMDQ0MDI0NNdRKsrPSS1WsopWSkzJzcxTitVRKi1OLcpMAaqCMPMSc1OVrJRKUotLQoFcQ6VaAAAAAP__.DsSib4mXUN7D0Ln0O-f1Eq19ojOp9c97OnLcnpbgsA0 

jwt优势

        无状态:由于jwt的playload特性,令牌的生产方式无需存储的,一旦令牌成功创建,如果没设置过期时间的话,那么这个令牌是可以一直用的,任何人拿到它,都可以使用。

        防篡改:由于jwt的signature特性,再私钥没有泄露的前提下,令牌是无法被篡改的,这也为无状态提供了支撑。

        通用性:由于是json格式的,所以JWT可以跨语言支持,比如Java、JavaScript、PHP、Node等等

jwt弊端

        无法中途废弃:因为一旦签发了一个 jwt,在到期之前始终都是有效的,如果用户信息发生更新了,只能等旧的 jwt 过期后重新签发新的 jwt。

        无法承载过多的用户信息:如果playload的内容非常多,那么jwt令牌将会是一个很长的字符串,面对复杂的权限系统,单靠playload负载用户信息是不够的,这又会违背了无状态的初衷。

jwt实现

maven依赖如下;

        <!-- JWT依赖 -->
        <dependency>
            <groupId>io.jsonwebtoken</groupId>
            <artifactId>jjwt</artifactId>
            <version>0.7.0</version>
        </dependency>
        <dependency>
            <groupId>com.auth0</groupId>
            <artifactId>java-jwt</artifactId>
            <version>3.4.0</version>
        </dependency>
        <!--JWT依赖,jdk1.8以上的还需引入以下依赖-->
        <dependency>
            <groupId>javax.xml.bind</groupId>
            <artifactId>jaxb-api</artifactId>
            <version>2.3.0</version>
        </dependency>
        <dependency>
            <groupId>com.sun.xml.bind</groupId>
            <artifactId>jaxb-impl</artifactId>
            <version>2.3.0</version>
        </dependency>
        <dependency>
            <groupId>com.sun.xml.bind</groupId>
            <artifactId>jaxb-core</artifactId>
            <version>2.3.0</version>
        </dependency>
        <dependency>
            <groupId>javax.activation</groupId>
            <artifactId>activation</artifactId>
            <version>1.1.1</version>
        </dependency>

代码如下

/*
     * @description: 创建jwt <br>
     * @create: 2023/4/10 10:42 <br>
     * @param playload 自定义的jwt载体
     * @return java.lang.String
     */
    public String createJwt(Map<String, Object> playload){
        JwtBuilder jwtBuilder = Jwts.builder();
        //设置加密算法和秘钥
        jwtBuilder.signWith(SignatureAlgorithm.HS256, jwt_security_key);
        //设置压缩压缩
        jwtBuilder.compressWith(CompressionCodecs.DEFLATE);
        //设置claims
        Claims claims = new DefaultClaims();
        //过期时间
        Date expiration = new Date(System.currentTimeMillis() + jwt_expiration);
        claims.setExpiration(expiration);
        //自定义参数
        claims.putAll(playload);
        jwtBuilder.setClaims(claims);
        return jwtBuilder.compact();
    }

    /*
     * @description: 校验jwt <br>
     * @create: 2023/4/10 15:09 <br>
     * @param jwtToken
     * @return boolean
     */
    public boolean checkJwt(String jwtToken){
        return Jwts.parser().isSigned(jwtToken);
    }

    /*
     * @description: 解析jwt <br>
     * @create: 2023/4/10 15:13 <br>
     * @param jwtToken
     * @return io.jsonwebtoken.Claims
     */
    public Claims parseJwt(String jwtToken){
        return Jwts.parser().setSigningKey(jwt_security_key).parseClaimsJws(jwtToken).getBody();
    }

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值