什么是JWT?
JWT是一种用于进行用户鉴权的技术。通过这个技术确定当前访问者的身份
代替了Session和Token的方式存储用户身份信息
实现方式
jwt通过了三段数据来记录所需要的信息
Header.Payload.Signature
Header
第一部分是头部分,它是一个描述JWT元数据的Json对象,通常如下所示。
{
"alg": "HS256",
"typ": "JWT"
}
alg属性表示签名使用的算法,默认为HMAC SHA256(写为HS256),typ属性表示令牌的类型,JWT令牌统一写为JWT。
最后,使用Base64 URL算法将上述JSON对象转换为字符串保存。
Payload
第二部分,也是一个json对象,除了包含需要传递的数据,还有七个字段可以选择
iss:发行人
exp:到期时间
sub:主题
aud:用户
nbf:在此之前不可用
iat:发布时间
jti:JWT ID用于标识该JWT
{
//默认字段
"sub":"主题123",
//自定义字段
"name":"java技术爱好者",
"isAdmin":"true",
"loginTime":"2021-12-05 12:00:03"
}
需要注意的是,默认情况下JWT是未加密的,任何人都可以解读其内容,因此如果一些敏感信息不要存放在此,以防信息泄露。
JSON对象也使用Base64 URL算法转换为字符串保存
Signature
第三部分是签名。是这样生成的,首先需要指定一个secret,该secret仅仅保存在服务器中,保证不能让其他用户知道。然后使用Header指定的算法对Header和Payload进行计算,然后就得出一个签名哈希。也就是Signature
那么Application Server如何进行验证呢?可以利用JWT前两段,用同一套哈希算法和同一个secret计算一个签名值,然后把计算出来的签名值和收到的JWT第三段比较,如果相同则认证通过。
JWT使用方法
- 导入maven依赖
```java
io.jsonwebtoken jjwt 0.9.1
2. 创建工具类,用于创建jwt字符串和解析jwt
```java
@Component
public class JwtUtil {
@Value("${jwt.secretKey}")
private String secretKey;
public String createJWT(String id, String subject, long ttlMillis, Map<String, Object> map) throws Exception {
JwtBuilder builder = Jwts.builder()
.setSubject(null) // 发行者
.setId(id)
.setSubject(subject)
.setIssuedAt(new Date()) // 发行时间
.signWith(SignatureAlgorithm.HS256, secretKey) // 签名类型 与 密钥
.compressWith(CompressionCodecs.DEFLATE);// 对载荷进行压缩
if (!CollectionUtils.isEmpty(map)) {
builder.setClaims(map);
}
if (ttlMillis > 0) {
builder.setExpiration(new Date(System.currentTimeMillis() + ttlMillis));
}
return builder.compact();
}
public Claims parseJWT(String jwtString) {
return Jwts.parser().setSigningKey(secretKey)
.parseClaimsJws(jwtString)
.getBody();
}
}
接着在application.yml配置文件配置jwt.secretKey
## 用户生成jwt字符串的secretKey jwt: secretKey: ak47
接着创建一个响应体 ```java public class BaseResponse {
private String code;
private String msg;
public static BaseResponse success() {
return new BaseResponse("0", "成功");
}
public static BaseResponse fail() {
return new BaseResponse("1", "失败");
} //构造器、getter、setter方法 }
public class JwtResponse extends BaseResponse {
private String jwtData;
public static JwtResponse success(String jwtData) {
BaseResponse success = BaseResponse.success();
return new JwtResponse(success.getCode(), success.getMsg(), jwtData);
}
public static JwtResponse fail(String jwtData) {
BaseResponse fail = BaseResponse.fail();
return new JwtResponse(fail.getCode(), fail.getMsg(), jwtData);
}
//构造器、getter、setter方法
} ```
- 通过三层架构调用相应的方法匹配用户的身份(从服务器里)