一、作为计算机术语时,是“令牌”的意思
token是计算机术语:令牌,令牌是一种能够控制站点占有媒体的特殊帧,以区别数据帧及其他控制帧。token其实说的更通俗点可以叫暗号,在一些数据传输之前,要先进行暗号的核对,不同的暗号被授权不同的数据操作。基于 Token 的身份验证方法
使用基于 Token 的身份验证方法,在服务端不需要存储用户的登录记录。大概的流程是这样的:
1.客户端使用用户名跟密码请求登录
2.服务端收到请求,去验证用户名与密码
3.验证成功后,服务端会签发一个 Token,再把这个 Token 发送给客户端
4.客户端收到 Token 以后可以把它存储起来,比如放在 Cookie 里或者 Local Storage 里
5.客户端每次向服务端请求资源的时候需要带着服务端签发的 Token
6.服务端收到请求,然后去验证客户端请求里面带着的 Token,如果验证成功,就向客户端返回请求的数据
二、定义
token:服务端生成的一串字符串,可以解决频繁登录的问题它作为客户端进行请求的一个令牌:
第一次登录后,服务器生成一个token返回给客户端;客户端只需要带上token来请求数据即可,无需再次带上用户名和密码;可以有效减轻服务器的压力,减少频繁的查询数据库,使服务器更加健壮。
三、token的组成部分
token分为三部分来定义:
1 .表头:Header是一个json对象,存储元数据
{
"alg":"HS256",
"typ":"JWT"
}
alg:是签名的算法名称(algorithm),默认是HMAC SHA);
type属性表示这个令牌(token)的类型(type),JWT令牌统一写成JWT。
2.负载:Payload是一个json对象。存放传递的数据,数据分为Public和Private。
Public是JWT中规定的一些字段,可以自己选择使用。
iss(issuer):签发人
exp(expiration time):过期时间
sub(subject):该JWT所面向的用户
aud(audience):受众,接受该JWT的一方
nbf(not before):生效时间
iat(Issued At):签发时间
jti(JWT ID):编号
Private是自己定义的字段
{
“role":经理,
"name":张凡,
"id":23455
}
Play默认是没有加密的,以上数据都是明文传输的,所以最好不要存放敏感数据。前两部分数据都是json对象使用的是base64URL编码,翻译为字符串。
3.Signature:签名。签名是对Header和Payload两部分的签名,目的是为了防止数据被篡改
HMACSHA256(
base64UrlEncoder(header)+"."+
base64UrlENcode(paylosd),
secret)
签名算法:先指定一个secret密匙,把base64URL的header,base64RL的payload和secret秘匙 使用HNAC SHA256生成签名字符串。
最后把三个部分的拼成一个字符串,每个部分之间用点(.)分隔,就可以返回给用户。
四、token 使用
1.生成token字符串
private long time=1000*60*60*24;
private String signature="admin";
@Test
public void jwt(){
JwtBuilder jwtBuilder= Jwts.builder();
// jwt三部分组成,Header,Payload,Signature
String jwtToken=jwtBuilder
//header
.setHeaderParam("typ","JWT")
.setHeaderParam("alg","HS256")
//payload
.claim("username","tom")
.claim("role","admin")
.setSubject("admin-test")
.setExpiration(new Date(System.currentTimeMillis()+time))
.setId(UUID.randomUUID().toString())
//Signature
.signWith(SignatureAlgorithm.HS256,signature)
//拼接字符串
.compact();
System.out.println(jwtToken);
}
2.对生成的token进行验证
@Test
public void parse(){
String token="eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VybmFtZSI6InRvbSIsInJvbGUiOiJhZG1pbiIsInN1YiI6ImFkbWluLXRlc3QiLCJleHAiOjE2NDA4NDY5NTAsImp0aSI6ImEwM2YwOGQ2LTFhNWItNGZkNi1hODQxLWM1YWIwYTUxZTZmNyJ9.Xv_ntmDtItl6_k_U40DqqKceDkhaYedRJ4h7Opr1wTE";
JwtParser jwtParser=Jwts.parser();
Jws<Claims> claimsJws=jwtParser.setSigningKey(signature).parseClaimsJws(token);
Claims claims =claimsJws.getBody();
System.out.println(claims.get("username"));
System.out.println(claims.getSubject());
System.out.println(claims.getExpiration());
}