您的位置:首页 > Web前端 > JavaScript

JWT (Json Web Token)教程

2018-01-17 15:54 603 查看
JWT(Json Web Token)是实现token技术的一种解决方案,JWT由三部分组成:
header(头)
payload(载体)
signature(签名)


JWT第一部分是header,header主要包含两个部分,alg指加密类型,可选值为
HS256
RSA
等等,
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;
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: