}
在编码前的JWT中,payload部分JSON中的属性被称为JWT的声明。JWT的声明分为两类:
(1)公有的声明(如iat)。
(2)私有的声明(自定义的JSON属性)。
公有的声明也就是JWT标准中注册的声明,主要为以下JSON属性:
(1)iss:签发人。
(2)sub:主题。
(3)aud:用户。
(4)iat:JWT的签发时间。
(5)exp:JWT的过期时间,这个过期时间必须要大于签发时间。
(6)nbf:定义在什么时间之前该JWT是不可用的。
私有的声明是除了公有声明之外的自定义JSON字段,私有的声明可以添加任何信息,一般添加用户的相关信息或其他业务需要的必要信息。下面的JSON例子中的uid、user_name、nick_name等都是私有声明。
{
“uid”: “123…”,
“sub”: “session id”,
“user_name”: “admin”,
“nick_name”: “管理员”,
“exp”: 1579317358,
“iat”: 1578453358
}
下面是一个向JWT令牌添加私有声明的实例,代码如下:
package com.crazymaker.demo.auth;
//省略import
@Slf4j
public class JwtDemo
{
/**
*测试私有声明
*/
@Test
public void testJWTWithClaim()
{
try
{
String subject = “session id”;
String salt = “user password”;
/**
*签名的加密算法
*/
Algorithm algorithm = Algorithm.HMAC256(salt);
//签发时间
long start = System.currentTimeMillis() - 60000;
//过期时间,在签发时间的基础上加上一个有效时长
Date end = new Date(start + SessionConstants.SESSION_TIME_OUT *1000);
/**
*JWT建造者
*/
JWTCreator.Builder builder = JWT.create();
/**
*增加私有声明
*/
builder.withClaim(“uid”, “123…”);
builder.withClaim(“user_name”, “admin”);
builder.withClaim(“nick_name”,“管理员”);
/**
*获取编码后的JWT令牌
*/
String token =builder
.withSubject(subject)
.withIssuedAt(new Date(start))
.withExpiresAt(end)
.sign(algorithm);
log.info(“token=” + token);
//以.分隔,这里需要转义
String[] parts = token.split(“\.” );
String payloadJson;
/**
*解码payload
*/
payloadJson = StringUtils.newStringUtf8
(Base64.decodeBase64(parts[1]));
log.info(“parts[1]=” + payloadJson);
//输出demo为:parts[1]=
//{“uid”:“123…”,“sub”:“session id”,“user_name”:“admin”,
“nick_name”:“管理员”,“exp”:1579317358,“iat”:1578453358}
} catch (Exception e)
{
e.printStackTrace();
}
}
}
由于JWT的payload声明(JSON属性)是可以解码的,属于明文信息,因此不建议添加敏感信息。
JWT+Spring Security认证处理流程
==========================
实际开发中如何使用JWT进行用户认证呢?疯狂创客圈的crazy-springcloud开发脚手架将JWT令牌和Spring Security相结合,设计了一个公共的、比较方便复用的用户认证模块base-auth。一般来说,在Zuul网关或者微服务提供者进行用户认证时导入这个公共的base-auth模块即可。
这里还是按照6.4.2节中请求认证处理流程的5个步骤介绍base-auth模块中JWT令牌的认证处理流程。
首先看第一步:定制一个凭证/令牌类,封装用户信息和JWT认证信息。
package com.crazymaker.springcloud.base.security.token;
//省略import
p