jwt 有3部分组成:(head、Payload、signature) 下面我们将分三步生成JWT的值。
头部:一般包含两部分
{
"typ": "JWT", // 固定为jwt
"alg": "HS256" // 加密算法
}
第一部分的值:将 Head 进行 Base64 加密就是 第一部分 的值。
荷载:包含公共部分与自定义部分
{
// 公共部分, 非强制可以省略。
"iss": "service-1", // jwt签发者
"sub": "all", // jwt所面向的用户
"aud": "service-2", // 接收jwt的一方
"exp": "2020-11-11", // jwt的过期时间,这个过期时间必须要大于签发时间
"nbf": "2020-10-01", // 定义在什么时间之前,该jwt都是不可用的.
"iat": "2020-01-01", // jwt的签发时间
"jti": "@!%^&$uyuyi", // jwt的唯一身份标识,主要用来作为一次性token,从而回避重放攻击。
// 自定义部分, 可以包含任何信息,因为不安全所以不要放敏感信息。
"name": "zhangsan",
"username": "admin"
}
第二部分的值:将 Payload 进行 Base64 加密就是 第二部分 的值。
签证信息:
第三部分的值:将 第一部分的值 与 第二部分的值 用 点 连接后,用 Head中alg 指定的加密方式加盐 secret 进行加密后就是 第三部分 的值。 其中盐 secret 的值由服务器保存,且不能泄漏。
JWT的值:将 第一部分的值 、 第二部分的值 、 第三部分的值 用 点 连接就是JWT的值。 JWT的格式:asdfasdf23.asdflkj.weo8rtuqyoei
用户登录成功后,服务器就根据用户的信息生成一个JWT,并返回给用户,接下来用户每次请求时都携带此JWT, 服务器首先验证该JWT是否是有效的JWT,若有效就解析该JWT,得到其中的 Payload 部分,其中可以根据公共部分的内容做是否过期等验证,若都符合就根据自定义部分的用户信息授予用户相关权限。
安全:
使用:
<dependency>
<groupId>com.auth0</groupId>
<artifactId>java-jwt</artifactId>
<version>3.18.2</version>
</dependency>
package com.jwt;
import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTCreator;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.Claim;
import com.auth0.jwt.interfaces.DecodedJWT;
import java.util.*;
public class JwtUtil {
private static String secret = "secret"; // 密钥
private static String issuer = "hjp"; // 发行者
private static Base64.Encoder encoder = Base64.getEncoder();
private static Base64.Decoder decoder = Base64.getDecoder();
// 生成jwt并base64编码
public static String genJwt(Map<String,Object> map){
String result = null;
try {
Algorithm algorithm = Algorithm.HMAC256(secret);
JWTCreator.Builder builder = JWT.create();
builder.withIssuer(issuer);
builder.withExpiresAt(new Date(System.currentTimeMillis()+(30*60*1000)));
Set<String> keys = map.keySet();
for (String key:keys) {
Object o = map.get(key);
if (o instanceof Date){
builder = builder.withClaim(key,(Date) o);
}else if (o instanceof String){
builder = builder.withClaim(key,(String) o);
}else if (o instanceof Integer){
builder = builder.withClaim(key,(Integer) o);
}else if (o instanceof Double){
builder = builder.withClaim(key,(Double) o);
}else if (o instanceof Boolean){
builder = builder.withClaim(key,(Boolean) o);
}
}
String sign = builder.sign(algorithm);
result = encoder.encodeToString(sign.getBytes("UTF-8"));
}catch (Exception e){
}
return result;
}
// 验证jwt
public static boolean valid(String token){
boolean result = false;
try{
String jwt = new String(decoder.decode(token), "UTF-8");
Algorithm algorithm = Algorithm.HMAC256(secret);
JWTVerifier verifier = JWT.require(algorithm)
.withIssuer(issuer)
.build();
DecodedJWT decodedJWT = verifier.verify(jwt);
result = true;
}catch (Exception e){
}
return result;
}
// 解析jwt
public static Map<String,Object> parseJwt(String token){
Map<String,Object> map = new HashMap<String, Object>();
try {
String jwt = new String(decoder.decode(token), "UTF-8");
Algorithm algorithm = Algorithm.HMAC256(secret);
DecodedJWT decodedJWT = JWT.decode(jwt);
Map<String, Claim> claims = decodedJWT.getClaims();
Set<String> keys = claims.keySet();
for (String key:keys) {
Claim claim = claims.get(key);
Object value;
try {
value = claim.as(String.class);
}catch (Exception e1){
try {
value = claim.as(Integer.class);
}catch (Exception e2){
try {
value = claim.as(Double.class);
}catch (Exception e3){
try {
value = claim.as(Boolean.class);
}catch (Exception e4){
continue;
}
}
}
}
map.put(key,value);
}
}catch (Exception e){
}
return map;
}
}
package com.jwt;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
public class Demo {
public static void main(String[] args) {
// 生成jwt
HashMap<String, Object> map = new HashMap<String, Object>();
map.put("name", "张三");
String jwt = JwtUtil.genJwt(map);
// 解析jwt
String token = "ZXlKMGVYQWlPaUpLVjFRaUxDSmhiR2NpT2lKSVV6STFOaUo5LmV5SnBjM01pT2lKb2FuQWlMQ0p1WVcxbElqb2k1YnlnNUxpSklpd2laWGh3SWpveE5qTTFOREV4TlRZM2ZRLkgzNXNDcHlyRUJHUWJFV1NFcERLWHhaUGVLM0pDdEN6bWpkd20yNVBrbVE=";
if (JwtUtil.valid(token)){
Map<String, Object> parseJwt = JwtUtil.parseJwt(token);
Set<String> strings = parseJwt.keySet();
for (String str: strings ) {
System.out.println(str+" : "+map.get(str));
}
}else {
System.out.println("jwt无效。");
}
}
}
JWT相关网站: JWT.IO
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/180894.html原文链接:https://javaforall.cn