JWT(Json Web Token)是实现token技术的一种解决方案,JWT由三部分组成:  header(头)payload(载体)signature(签名)

JWT第一部分是header,header主要包含两个部分,alg指加密类型,可选值为HS256RSA等等,typ=JWT为固定值,表示token的类型。。

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

JWT第二部分是payload,payload是token的详细内容,一般包括iss (发行者), exp (过期时间), sub(用户信息), aud (接收者),以及其他信息,详细介绍请参考官网,也可以包含自定义字段。

{
    "iat": 1493090001,
    "name": "张三"
}
iss:Issuer,发行者
sub:Subject,主题
aud:Audience,观众
exp:Expiration time,过期时间
nbf:Not before
iat:Issued at,发行时间
jti:JWT ID
签名

JWT第二部分是signature,这部分的内容是这样计算得来的:

Base64(header).Base64(payload)得到一个Base64编码的字符串(下文成EncodeString)
HS256(EncodeString,"秘钥");计算得到的即使签名。
计算得到上面三部分内容后,用.连接起来就是一个完整的 JWT TOKEN,秘钥是保存在服务器上的一个私有密钥。

将头部、声明、签名用.号连在一起就得到了我们要的JWT。

eyJhbGciOiJIUzI1NiJ9.eyJleHAiOjE1MTUyOTgxNDEsImtleSI6InZhdWxlIn0.orewTmil7YmIXKILHwFnw3Bq1Ox4maXEzp0NC5LRaFQ
和Session方式存储id的差异

Session方式存储用户id的最大弊病在于要占用大量服务器内存,对于较大型应用而言可能还要保存许多的状态。一般而言,大型应用还需要借助一些KV数据库和一系列缓存机制来实现Session的存储。

而JWT方式将用户状态分散到了客户端中,可以明显减轻服务端的内存压力。除了用户id之外,还可以存储其他的和用户相关的信息,例如用户角色,用户性别等。

java 使用 jwt

引入jar

<!--JWT-->
<dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt</artifactId>
    <version>0.9.0</version>
</dependency>

demo

package user;

import io.jsonwebtoken.*;
import org.joda.time.DateTime;
import org.junit.Test;

import java.util.Date;

public class JWT {
    private static final String PRIVATE_KEY = "123456789";

    @Test
    public void jwtTest() throws InterruptedException {
        // 设置3秒后过期
        String jwt = this.buildJwt(DateTime.now().plusSeconds(3).toDate());
        System.out.println(jwt);
        // 验证token是否可用
        boolean isOk = this.isJwtValid(jwt);
        System.out.println(isOk);
    }

    public String buildJwt(Date exp) {
        String jwt = Jwts.builder()
                .signWith(SignatureAlgorithm.HS256, PRIVATE_KEY)//SECRET_KEY是加密算法对应的密钥,这里使用额是HS256加密算法
                .setExpiration(exp)//expTime是过期时间
                .claim("key", "vaule")//该方法是在JWT中加入值为vaule的key字段
                .compact();
        return jwt;
    }

    public boolean isJwtValid(String jwt) {
        try {
            //解析JWT字符串中的数据,并进行最基础的验证
            Claims claims = Jwts.parser()
                    .setSigningKey(PRIVATE_KEY)//SECRET_KEY是加密算法对应的密钥,jjwt可以自动判断机密算法
                    .parseClaimsJws(jwt)//jwt是JWT字符串
                    .getBody();
            String vaule = claims.get("key", String.class);//获取自定义字段key
            //判断自定义字段是否正确
            if ("vaule".equals(vaule)) {
                return true;
            } else {
                return false;
            }
        }
        //在解析JWT字符串时,如果密钥不正确,将会解析失败,抛出SignatureException异常,说明该JWT字符串是伪造的
        //在解析JWT字符串时,如果‘过期时间字段’已经早于当前时间,将会抛出ExpiredJwtException异常,说明本次请求已经失效
        catch (SignatureException | ExpiredJwtException e) {
            return false;
        }
    }
}


GitHub 加速计划 / js / json
18
5
下载
适用于现代 C++ 的 JSON。
最近提交(Master分支:2 个月前 )
6be4e856 2 天前
663058e7 5 天前
Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐