前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >JWT原理讲解_达林顿管工作原理

JWT原理讲解_达林顿管工作原理

作者头像
全栈程序员站长
发布2022-11-02 11:34:11
2400
发布2022-11-02 11:34:11
举报
文章被收录于专栏:全栈程序员必看

JWT (JSON WEB TOKEN)

jwt 有3部分组成:(head、Payload、signature) 下面我们将分三步生成JWT的值。

1. Head
代码语言:javascript
复制
头部:一般包含两部分  
代码语言:javascript
复制
{ 
   
  "typ": "JWT", // 固定为jwt
  "alg": "HS256" // 加密算法
}

第一部分的值:将 Head 进行 Base64 加密就是 第一部分 的值。

2. Payload
代码语言:javascript
复制
荷载:包含公共部分与自定义部分
代码语言:javascript
复制
{ 
   
	// 公共部分, 非强制可以省略。
	"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 加密就是 第二部分 的值。

3. Signature

签证信息:

第三部分的值:将 第一部分的值第二部分的值 连接后,用 Head中alg 指定的加密方式加盐 secret 进行加密后就是 第三部分 的值。 其中盐 secret 的值由服务器保存,且不能泄漏。

4. JWT的值

JWT的值:将 第一部分的值第二部分的值第三部分的值 连接就是JWT的值。 JWT的格式:asdfasdf23.asdflkj.weo8rtuqyoei

5. 使用

用户登录成功后,服务器就根据用户的信息生成一个JWT,并返回给用户,接下来用户每次请求时都携带此JWT, 服务器首先验证该JWT是否是有效的JWT,若有效就解析该JWT,得到其中的 Payload 部分,其中可以根据公共部分的内容做是否过期等验证,若都符合就根据自定义部分的用户信息授予用户相关权限。

6. 总结

安全:

  • 由于 Payload 使用Base64算法加密,所以其中不能放置用户的敏感信息。
  • 服务器端保存的Signature中的 secret 一定不能泄露,由于JWT使用第三部分Signature做数组签名,第三方在不知道 secret 的情况下是无法伪造的,但一旦 secret 泄露,第三方就可以随意伪造JWT。
  • 尽量使用https协议,由于http是明文传输,如果中间有人抓包,就可以获取用户的JWT,变相的就拥有了用户的权限。
  • 尽量设置过期时间,由于JWT长期有效(即使用户更改密码JWT也不会失效),所以JWT的失效不受用户控制。
  • 每次生成JWT时,为了安全可以在Payload部分的jti中加入token。

使用:

  • JWT的生成、验证、解析,一般由实现 JWT 的第三方jar包提供。
  • 我们可以解析JWT后根据其中的 Payload 进行一些验证,比如是否过期,以及IP地址等。
7. java使用入门
  1. 引入依赖:
代码语言:javascript
复制
<dependency>
    <groupId>com.auth0</groupId>
    <artifactId>java-jwt</artifactId>
    <version>3.18.2</version>
</dependency>
  1. 定义工具类
代码语言:javascript
复制
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;
}
}
  1. 调用工具类
代码语言:javascript
复制
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无效。");
}
}
}
8.其他

JWT相关网站: JWT.IO

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/180894.html原文链接:https://javaforall.cn

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022年10月17日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • JWT (JSON WEB TOKEN)
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档