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

JWT原理讲解_达林顿管工作原理JWT(JSONWEBTOKEN)jwt有3部分组成:(head、Payload、signature)下面我们将分三步生成JWT的值。1.Head头部:一般包含两部分{“typ”:”JWT”,//固定为jwt”alg”:”HS256″//加密算法}第一部分的值:将Head进行Base64加密就是第一部分的值。2.Payload荷载:包含公共部分与自定义部分{ //公共部分,非强制可以省略。 “iss”:”servic

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE稳定放心使用

JWT (JSON WEB TOKEN)

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

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

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

2. Payload
荷载:包含公共部分与自定义部分
{ 
   
	// 公共部分, 非强制可以省略。
	"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. 引入依赖:
<dependency>
    <groupId>com.auth0</groupId>
    <artifactId>java-jwt</artifactId>
    <version>3.18.2</version>
</dependency>
  1. 定义工具类
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. 调用工具类
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

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

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

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • RSA加密算法简介[通俗易懂]

    RSA加密算法简介[通俗易懂]背景RSA加密算法是公钥密码最著名的算法之一,是由MIT三位(RonRivest,AdiShamir,LenAdleman)提出的,也就以三位的名字首字母命名。该算法的理论基础是“大数分解和素数检测“,如果说有一天,大数分解和素数检测的数学理论被证明可以简单解决,那么RSA算法的加密将没有任何意义。有提出说量子计算机的出现可以大大提高RSA的破解效率。下面我们将简单学习RSA加密算法的

  • java开发规范(个人理解)

    java开发规范(个人理解)

  • Android中Context具体解释 —- 你所不知道的Context

    Android中Context具体解释 —- 你所不知道的Context

    2021年12月15日
  • 开源渗透测试工具_渗透测试实战

    开源渗透测试工具_渗透测试实战渗透测试工具库,黑客工具,脚本,APT攻击,痕迹清除,

  • Linux基本操作命令 实验

    Linux基本操作命令 实验一、实验目的:1. 熟悉Linux基本命令。2. 熟悉Linux操作系统。二、实验环境:一台装有Linux的机器。三、实验内容:1.文件操作命令的使用。用vi编辑器新建一个testl文件输入thisistestl~!查看文件与目录ls进入Linux系统,输入ls-m按回车键执行。 一、实验目的:1. 熟悉Linux基本命令。2. 熟悉Linux操作系统。 二、实验环境:一台装有Linux的机器…

  • 【redis源码学习】系列目录导航[通俗易懂]

    【redis源码学习】系列目录导航[通俗易懂]万幸,赶在2022之前完成了这个系列,哈哈。【redis源码学习】redisObject【redis源码学习】simpledynamicstrings(简单动态字符串sds)【redis源码学习】跳跃表【redis源码学习】redis专属“链表”:ziplist【redis源码学习】快速列表quicklist【redis源码学习】看看redis的“哈希表”实现【redis源码学习】redis启动并读取配置文件的过程【redis源码学习】紧凑列表listpack,t_hash的御.

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号