JWT简介及优缺点(附Java版示例)

2023-12-25 19:15:48

JWT (JSON Web Token) 简介

JSON Web Token(JWT)是一种开放标准(RFC 7519),用于在各方之间安全地传输信息作为JSON对象。在Web应用中,JWT通常用于身份验证和信息交换,它使得在服务提供者和服务消费者之间传递安全可信的声明成为可能。

JWT由三部分组成,它们之间用点(.)分隔开:

  1. Header(头部):通常包含令牌的类型(即JWT)和所使用的签名算法(如HMAC SHA256或RSA)。
  2. Payload(有效载荷):包含所谓的claims(声明),声明是关于实体(通常是用户)和其他数据的语句。
  3. Signature(签名):用于验证消息在传输途中未被篡改,并且,对于使用私钥签名的令牌,它还可以验证JWT的发送者是谁。

优点

  1. 自包含:JWT包含了所有用户需要的信息,避免了多次数据库查询。
  2. 可扩展性:由于其小巧的大小,JWT非常适合分布式站点进行单点登录(SSO)。
  3. 跨语言支持:JWT支持所有主流编程语言。
  4. 性能:由于JWT的自包含特性,它减少了需要在服务之间传递的回合数。
  5. 安全性:JWT可以使用对称加密(HMAC)或非对称加密(RSA)进行签名。

缺点

  1. 存储空间:如果Payload太大,会增加每次请求的开销。
  2. 安全性风险:如果没有正确使用和管理(如不使用HTTPS),JWT可能会被拦截。
  3. 不可撤销:一旦JWT被签发,在有效期内将会一直有效,除非服务器部署额外的逻辑来拒绝某些令牌。
  4. 密钥安全:对于使用对称加密的JWT,如果密钥泄露,任何人都可以签发令牌。

使用场景

  • 身份验证:用户登录后,每个后续请求将包括JWT,允许用户访问允许的路由、服务和资源。
  • 信息交换:JWT是在两个系统之间安全传输信息的好方法,因为可以对JWT进行签名,比如使用公钥/私钥对。

示例(基于Java)

以下是使用Java创建和验证JWT的一个简单示例。这个例子使用了jjwt库,这是一个流行的Java库,用于创建和验证JSON Web Tokens。

首先,您需要将jjwt库添加到您的项目中,如果您使用的是Maven,可以添加以下依赖:

<dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt</artifactId>
    <version>0.9.1</version>
</dependency>

创建JWT的代码如下:

import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import java.util.Date;

public class JwtExample {

    public static String createJWT(String id, String issuer, String subject, long ttlMillis) {

        long nowMillis = System.currentTimeMillis();
        Date now = new Date(nowMillis);

        // 签名算法以及密钥
        SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;
        byte[] apiKeySecretBytes = DatatypeConverter.parseBase64Binary("your-secret-key");

        // 设置JWT Claims
        JwtBuilder builder = Jwts.builder().setId(id)
                .setIssuedAt(now)
                .setSubject(subject)
                .setIssuer(issuer)
                .signWith(signatureAlgorithm, apiKeySecretBytes);

        // 设置过期时间
        if (ttlMillis > 0) {
            long expMillis = nowMillis + ttlMillis;
            Date exp = new Date(expMillis);
            builder.setExpiration(exp);
        }

        // 构建JWT并将其序列化为一个紧凑的、URL安全的字符串
        return builder.compact();
    }

    public static void main(String[] args) {
        String jwt = createJWT("id", "issuer", "subject", 3600000); // 设置1小时后过期
        System.out.println("JWT: " + jwt);
    }
}

验证JWT的代码如下:

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;

public class JwtParserExample {

    public static void parseJWT(String jwt) {

        // 这里的密钥要与生成JWT使用的密钥一致
        byte[] apiKeySecretBytes = DatatypeConverter.parseBase64Binary("your-secret-key");

        // 解析JWT字符串
        Claims claims = Jwts.parser()
                .setSigningKey(apiKeySecretBytes)
                .parseClaimsJws(jwt).getBody();

        System.out.println("ID: " + claims.getId());
        System.out.println("Subject: " + claims.getSubject());
        System.out.println("Issuer: " + claims.getIssuer());
        System.out.println("Expiration: " + claims.getExpiration());
    }

    public static void main(String[] args) {
        String jwt = "your.jwt.token.here";
        parseJWT(jwt);
    }
}

请注意,您需要将your-secret-key替换为实际的密钥,并确保在创建和解析JWT时使用相同的密钥。同样,your.jwt.token.here应该是您实际接收到的JWT字符串。

文章来源:https://blog.csdn.net/lpw_cn/article/details/135145343
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。