首页 > 其他分享 >JWT

JWT

时间:2023-08-29 14:47:10浏览次数:30  
标签:JWT jwt Header token 签名 Payload

什么是JWT:

JWT (JSON Web Token) 是目前最流行的跨域认证解决方案,是一种基于 Token 的认证授权机制。 从 JWT 的全称可以看出,JWT 本身也是 Token,一种规范化之后的 JSON 结构的 Token。

JWT 自身包含了身份验证所需要的所有信息,因此,我们的服务器不需要存储 Session 信息。这显然增加了系统的可用性和伸缩性,大大减轻了服务端的压力。

可以看出,JWT 更符合设计 RESTful API 时的「Stateless(无状态)」原则 。

并且, 使用 JWT 认证可以有效避免 CSRF 攻击,因为 JWT 一般是存在在 localStorage 中,使用 JWT 进行身份验证的过程中是不会涉及到 Cookie 的。

什么时候你应该用JSON Web Tokens

常见的API 鉴权,用户凭证:一般应用在接口认证;每次请求获取数据接口都要求传token;

适用于分布式站点的单点登录(SSO)场景。JWT的声明一般被用来在身份提供者和服务提供者间传递被认证的用户身份信息,以便于从资源服务器获取资源,也可以增加一些额外的其它业务逻辑所必须的声明信息,该token也可直接被用于认证,也可被加密。

下列场景中使用JSON Web Token是很有用的:

  • Authorization (授权) : 这是使用JWT的最常见场景。一旦用户登录,后续每个请求都将包含JWT,允许用户访问该令牌允许的路由、服务和资源。单点登录是现在广泛使用的JWT的一个特性,因为它的开销很小,并且可以轻松地跨域使用。
  • Information Exchange (信息交换) : 对于安全的在各方之间传输信息而言,JSON Web Tokens无疑是一种很好的方式。因为JWTs可以被签名,例如,用公钥/私钥对,你可以确定发送人就是它们所说的那个人。另外,由于签名是使用头和有效负载计算的,您还可以验证内容没有被篡改。

JWT 数据结构:

JWT 本质上就是一组字串,通过(.)切分成三个为 Base64 编码的部分:

  • Header : 描述 JWT 的元数据,定义了生成签名的算法以及 Token 的类型。

  • Payload : 用来存放实际需要传递的数据

  • Signature(签名) :服务器通过 Payload、Header 和一个密钥(Secret)使用 Header 里面指定的签名算法(默认是 HMAC SHA256)生成。

JWT 通常是这样的:xxxxx.yyyyy.zzzzz

Header

Header 通常由两部分组成:

  • typ(Type):令牌类型,也就是 JWT。

  • alg(Algorithm) :签名算法,比如 HS256。

示例:

{
 "alg": "HS256",
 "typ": "JWT"
}

JSON 形式的 Header 被转换成 Base64 编码,成为 JWT 的第一部分。

jwt中的三种算法:

  • HMAC【哈希消息验证码(对称)】:HS256/HS384/HS512
  • RSASSA【RSA签名算法(非对称)】(RS256/RS384/RS512)
  • ECDSA【椭圆曲线数据签名算法(非对称)】(ES256/ES384/ES512)

 

对称加密中: secretKey指加密密钥,用来生成签名与验签;

非对称加密中: secretKey指私钥,只用来生成签名,但是不能用来验签(验签用的是公钥);

对称加密中使用同一个密钥进行加密与解密,因此这时候公钥不能泄漏,因此对称算法只适合服务端内部使用,不适合网络第三方,

非对称加密通常服务端有私钥和公钥,使用私钥加密,使用公钥可以解密,相对来说更安全

Payload

payload也是 JSON 格式数据,其中包含了 Claims(声明,包含 JWT 的相关信息)。

Claims 分为三种类型:

  • Registered Claims(注册声明) :预定义的一些声明,建议使用,但不是强制性的。

  • Public Claims(公有声明) :JWT 签发方可以自定义的声明,但是为了避免冲突,应该在 IANA JSON Web Token Registry 中定义它们。

  • Private Claims(私有声明) :JWT 签发方因为项目需要而自定义的声明,更符合实际项目场景使用。

下面是一些常见的注册声明:

  • iss(issuer):JWT 签发方。

  • iat(issued at time):JWT 签发时间。

  • sub(subject):JWT 主题。

  • aud(audience):JWT 接收方。

  • exp(expiration time):JWT 的过期时间。

  • nbf(not before time):JWT 生效时间,早于该定义的时间的 JWT 不能被接受处理。

  • jti(JWT ID):JWT 唯一标识。

也可以自定义;

示例:

{
 "uid": "ff1212f5-d8d1-4496-bf41-d2dda73de19a",
 "sub": "1234567890",
 "name": "John Doe",
 "exp": 15323232,
 "iat": 1516239022,
 "scope": ["admin", "user"]
}

Payload 部分默认是不加密的,一定不要将隐私信息存放在 Payload 当中!!!

JSON 形式的 Payload 被转换成 Base64 编码,成为 JWT 的第二部分。

Signature

Signature 部分是对前两部分的签名,作用是防止 JWT(主要是 payload) 被篡改。

这个签名的生成需要用到:

  • Header + Payload。

  • 存放在服务端的密钥(一定不要泄露出去)。

  • 签名算法。

签名的计算公式如下:

比如使用 HMAC SHA256 算法进行签名

HMACSHA256(
base64UrlEncode(header) + "." +
base64UrlEncode(payload),
secret)

算出签名以后,把 Header、Payload、Signature 三个部分拼成一个字符串,每个部分之间用"点"(.)分隔,这个字符串就是 JWT 。

在基于 JWT 进行身份验证的的应用程序中,服务器通过 Payload、Header 和 Secret(密钥)创建 JWT 并将 JWT 发送给客户端。客户端接收到 JWT 之后,会将其保存在 Cookie 或者 localStorage 里面,以后客户端发出的所有请求都会携带这个令牌。

jwt使用:

  1. 应用(或者客户端)想授权服务器请求授权。例如,如果用授权码流程的话,就是/oauth/authorize
  2. 当授权被许可以后,授权服务器返回一个access token给应用,token 就是eccodeheader.eccodepayload.signature
  3. 应用使用access token访问受保护的资源(比如:API)

token是服务端给客户端的,客户端每次请求需要在header中带上token,然服务验证,服务通过了验证,才能返回请求的数据;

java-jwt的使用

 引入jar:

 

<dependency>
            <groupId>com.auth0</groupId>
            <artifactId>java-jwt</artifactId>
            <version>3.10.3</version>
        </dependency>

 

demo:

 1 package org.muses.ssm.demo.mgt.mock.test;
 2 
 3 import java.util.Calendar;
 4 import java.util.HashMap;
 5 import java.util.Map;
 6 
 7 import com.auth0.jwt.JWT;
 8 import com.auth0.jwt.JWTCreator;
 9 import com.auth0.jwt.JWTVerifier;
10 import com.auth0.jwt.algorithms.Algorithm;
11 import com.auth0.jwt.interfaces.Claim;
12 import com.auth0.jwt.interfaces.DecodedJWT;
13 
14 /**
15  * @author lixm
16  * @date 2023/8/29 11:51
17  */
18 public class JwtUtils {
19     /**
20      * key(按照签名算法的字节长度设置key)
21      */
22     private final static String SECRET_KEY = "!34ADAS";
23     /**
24      * 过期时间(毫秒单位)
25      */
26     private final static int TOKEN_EXPIRE_MILLIS = 1000 * 60 * 60;
27 
28     public static String getToken(Map<String, String> map) {
29         // 指定token过期时间
30         Calendar calendar = Calendar.getInstance();
31         calendar.add(Calendar.MILLISECOND, TOKEN_EXPIRE_MILLIS);
32         JWTCreator.Builder builder = JWT.create();
33         Map<String, Object> head = new HashMap<String, Object>();
34         if (map != null && !map.isEmpty()) {
35             for (String key : map.keySet()) {
36                 builder.withClaim(key, map.get(key));
37             }
38         }
39         builder.withExpiresAt(calendar.getTime());
40         return builder.sign(Algorithm.HMAC256(SECRET_KEY)).toString();
41     }
42 
43     public static Map<String, Object> parseToken(String token) {
44         Map<String, Object> res = new HashMap<>();
45         try {
46             // 创建解析对象,使用的算法和secret要与创建token时保持一致
47             JWTVerifier jwtVerifier = JWT.require(Algorithm.HMAC256(SECRET_KEY)).build();
48             // 解析指定的token
49             DecodedJWT decodedJWT = jwtVerifier.verify(token);
50             // 获取解析后的token中的payload信息
51             Map<String, Claim> map = decodedJWT.getClaims();
52 
53             for (String key : map.keySet()) {
54                 res.put(key, map.get(key).as(Object.class));
55             }
56             // 因为有超时时间,所以可能可能超时,输出超时时间
57             System.out.println(decodedJWT.getExpiresAt());
58         } catch (Exception e) {
59             System.out.println(e.getMessage());
60         }
61 
62         return res;
63 
64     }
65 
66     public static void main(String[] args) {
67         Map<String, String> claim = new HashMap<String, String>();
68         claim.put("userId", 21 + "");
69         claim.put("userName", "baobao");
70         String token = JwtUtils.getToken(claim);
71         System.out.println(JwtUtils.getToken(claim));
72         System.out.println(JwtUtils.parseToken(token));
73     }
74 
75 }

执行结果:

eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyTmFtZSI6ImJhb2JhbyIsImV4cCI6MTY5MzI5NDA0MCwidXNlcklkIjoiMjEifQ._6yhDh0XV3AINv_1jkyGga9cR8UCEvYuOQqQBejKqIc
Tue Aug 29 15:27:18 CST 2023
{userName=baobao, exp=1693294038, userId=21}

说明:exp返回了时间戳;

参考地址:

https://www.cnblogs.com/cjsblog/p/9277677.html 

https://www.cnblogs.com/yanglei2022/p/16689375.html

 

 

 

 

标签:JWT,jwt,Header,token,签名,Payload
From: https://www.cnblogs.com/lixiuming521125/p/17653487.html

相关文章

  • JWT
    一.JWT的作用 把JSON对象加密成为一个秘钥字符串,JWT的令牌由三个部分组成 JWT头,JWTToken  签名 二.验证令牌的流程首先由用户登录后将信息传到后台接口中生成JWT令牌,然后后台将JWT令牌返回给前端,前端可以保存到localStorage或sessionStoeage中前端每次访问请求时会带......
  • gRPC with JWT
    在gRPC中使用JWT(JSONWebTokens)进行身份验证是一种常见的做法,它可以帮助你确保请求方的身份和权限。下面是一种使用gRPC和JWT进行身份验证的步骤:生成和签发JWT:在用户登录成功后,你需要生成一个JWT并将其签发给用户。JWT中可以包含一些有关用户身份、角色、权限等的......
  • 如何在.Net6.0中使用JWT
    JWT全名JSONWebToken用来进行我们的Api进口保护,那么这个JWT该怎么使用:首先我们需要下载NuGet包: 然后下载这两个NuGet包第一个是JWT的官方包用来进行和核心操作,第二个是用来进行鉴权用。那麽现在我么就要开始配置JWT了首先我们需要创建一个类:定义注册存入TokenHelper类,方......
  • JWT
    .Net6WebAPI使用JWT进行授权认证1、安装组件(Nuget)Microsoft.AspNetCore.Authentication.JwtBearer 2、Program.cs 配置//授权认证(使用JWT)builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme).AddJwtBearer(o=>{//私钥varsec......
  • .NET6 设置JWT
    一、Net6环境下的.netcore项目里如何使用JWT。第一步,在Nuget引入JWT、Microsoft.AspNetCore.Authentication.JwtBearer这两个NuGet包 第二步,在appsettings.json配置相关配置 第三步,在Program.cs中注册 第四步,定义注册存入TokenHelper类,方便对J......
  • .NET 6 JWT验证
    一、下载JWT包二、配置文件appsettings.json"Auth":{"SecretKey": "al45jgioasdjgoije8343050945049jg3409jgfoksdjfglaskdjfaiosdjfasdfsd",//私钥长度16位以上"Issuer":"www.aaabb.com",//发行人"Aud......
  • 深入探讨安全验证:OAuth2.0、Cookie与Session、JWT令牌、SSO与开放授权平台设计
    什么是认证和授权?如何设计一个权限认证框架?认证和授权是安全验证中的两个重要概念。认证是确认身份的过程,用于建立双方之间的信任关系。只有在认证成功的情况下,双方才可以进行后续的授权操作。授权则是在认证的基础上,确定用户或系统对资源的访问权限。在设计一个权限认证框架时,......
  • JSON Web Tokens(JWT)
    JSONWebTokens(JWT)是一种用于身份验证和授权的开放标准。它可以在客户端和服务器之间安全地传输信息,并且非常适合以下场景:身份验证:JWT可以用于验证用户的身份。当用户登录后,服务器可以生成一个JWT并将其返回给客户端。客户端可以在后续的请求中将JWT作为身份验证凭证发送给服务器......
  • token和jwt
    1. 简介  105使用Token存储用户信息,认证用户。 Token是一个访问系统的令牌(字符串)。Token 是在服务端产生的。前端可以使用用户名/密码向服务端请求认证(登录),服务端认证成功,服务端会返回 Token 给前端。前端可以在每次请求的时候带上 Token 证明自己的身份。服务器端在处理......
  • C#利用Refit实现JWT自动续期
    前言笔者之前开发过一套C/S架构的桌面应用,采用了JWT作为用户的登录认证和授权。遇到的唯一问题就是JWT过期了该怎么办?设想当一个用户正在进行业务操作,突然因为Token过期失效,莫名其妙地跳转到登录界面,是不是一件很无语的事。当然笔者也曾想过:为何不把JWT的有效期尽量设长些(假设24......