前言:
以往服务器鉴权的方式大多是使用Session,在初次登陆系统后,用户的信息将会记录在session中,后续再次访问时,页面只需发送session即可,无需再次验证信息。
使用session验证的方式会有这样的一个问题:所有的登陆信息都存储在服务端,当访问量特别大的时候服务端的压力会比较大。并且在做单点登录或者分布式服务的时候,涉及如何实现session共享的问题。
什么是JWT?
JWT全称为JSON WEB TOKENS,是一种基于token的验证方式。实际上就是一串加密的JSON串,该JSON串通过一个KEY来加密,该KEY保存在服务端,当客户端第一次登陆服务端时,服务端会返回改JSON串至客户端,在客户端后续请求中,只要再将改JSON串发送至服务器即可通过验证。在WEB环境下可以使用cookie来实现此流程,在用户登陆后将JWT放入cookie中,并设置cookie头,下次客户端请求时会自动将带着JWT的cookie发送回服务端。
可以用JWT来做什么?
1.系统间的鉴权。
2.加密数据传输。
JWT的格式是怎样的?
上面说JWT是一个JSON串,这不准确,应该说加密前是个JSON结构。这个结构分为三个部分:
Header,payload,signature
Header如下:
{
"alg": "HS256",
"typ": "JWT"
}
alg为加密方式,type为Token类型,header被加密成base64。
payload如下:
{
"sub": "1234567890",
"name": "John Doe",
"admin": true
}
payload为实际存储内容,不要在这里存储重要信息,playload会被加密成base64。
signature为加密签名:
HMACSHA256(
base64UrlEncode(header) + "." +
base64UrlEncode(payload),
secret)
最终形态的JWT数据为:
eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJURVNUIiwiZXhwIjoxNTM4MTIxOTg5fQ.P9OsHjSu4K4PCHBMaRQhb_bHHyt2bLYqalPqXZrzzh0
JAVA中如何使用JWT?
引用POM:
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-api</artifactId>
<version>0.10.5</version>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-impl</artifactId>
<version>0.10.5</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-jackson</artifactId>
<version>0.10.5</version>
<scope>runtime</scope>
</dependency>
如何生成JWT?
Key key = new SecretKeySpec(UUID.randomUUID().toString().replace("-","").getBytes(), SignatureAlgorithm.HS256.getJcaName());
Claims claims = Jwts.claims().setSubject("TEST");
String jws = Jwts.builder()
.setSubject("TEST")
.setClaims(claims)
.setExpiration(new Date(System.currentTimeMillis() + 10000))
.signWith(key)
.compact();
如何解析JWT?
Jws<Claims> claimsJws=Jwts.parser().setSigningKey(key).parseClaimsJws(jws);
Object value=claimsJws.getBody().get("parma");