大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新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使用入门
- 引入依赖:
<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无效。");
}
}
}
8.其他
JWT相关网站: JWT.IO
发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/180894.html原文链接:https://javaforall.cn
【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛
【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...