什么是JWT
Json web token。一般被用来在身份提供者和服务提供者间传递被认证的用户身份信息,以便于从资源服务器获取资源。
为什么用JWT
session认证信息要记录在服务端。通常保存在内存,用户增多开销增大。分布式情况下影响负载均衡和应用扩展。
基于token的认证机制类似http协议是无状态的。不需要再服务端保留用户的认证信息。所以应用不需要考虑用户在那一台服务器登录,有利于应用扩展。
简要流程
用户使用用户名密码请求服务器
服务器验证用户信息,通过验证发送给用户一个token
客户端存储token,每次请求附带这个token。
服务端(不一定是签发token的服务器,可以是任何一个)验证token值,返回数据。
JWT的构成
三段信息:头部header+载荷payload+签证signature。
header
声明类型和声明加密算法
{
'typ': 'JWT',
'alg': 'HS256'
}
然后用base64加密(对称加密,可以解密)
构成第一部分。
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9
playload
一个json包括:
标准中注册的声明
公共的声明
私有的声明
其中私有声明是提供者和消费者共同定义的,因为使用base64相当于明文,不能存放敏感信息。这里构成jwt第二部分。
signature
签证信息:
base64加密过后的header.payload
然后使用header中声明的加密方式,依据服务端提供的一个secret进行加盐组合加密。
这就是jwt的第三部分。
注意
secret是服务器的私钥,不能泄露。
第一部分和第二部分base64加密都可以解密。
JWT的使用
添加依赖
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.9.1</version>
</dependency>
配置文件
放在resource包下
jwt.properties
jwt.secret=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
jwt.expiration=6000000
Service类
创建JwtService类
配置文件信息注入
@Service
@PropertySource("classpath:jwt.properties")
public class JwtService {
@Value("${jwt.secret}")
private String secret;
@Value("${jwt.expiration}")
private Long expiration;
public String generateToken(String content) {
Map<String, Object> claims = new HashMap<>();
claims.put(Claims.SUBJECT, content);
claims.put(Claims.ISSUED_AT, new Date());
Date expirationDate = new Date(System.currentTimeMillis() + expiration);
return Jwts.builder()
.setClaims(claims)
.setExpiration(expirationDate)
.signWith(SignatureAlgorithm.HS512, secret)
.compact();
}
}
使用
这里简要描述一下,一般使用组合方式注入jwtService
JwtService jwtService= new JwtService();
String token = jwtService.generateToken(uid)