5. JWT令牌
5.1 JWT令牌概念
JWT (JSON Web Token) 是一种用于在网络应用程序之间安全传输信息的开放标准(RFC 7519)。JWT 令牌是一种轻量级的令牌,它包含了一些关键信息,比如用户身份、权限等,并使用数字签名进行验证,以确保该信息在传输过程中不被篡改或伪造。
5.2 JWT令牌构成
JWT 令牌的格式是由 RFC 7519 标准规定的,由三部分组成:头部(Header)、载荷(Payload)和签名(Signature)。头部包含了令牌类型和加密算法等信息,载荷包含了需要传输的信息,例如用户 ID、角色、权限等,签名则是将头部和载荷进行加密后得到的结果,用于验证令牌是否被篡改。
使用 JWT 令牌的好处是可以方便地在不同的应用程序或服务之间共享用户身份信息,而无需每次都进行身份验证。此外,因为 JWT 令牌是基于标准的 JSON 格式,因此易于使用和传输。
假设一个网站需要验证用户身份并授权用户访问某些受保护的资源。使用 JWT 令牌,用户登录后,服务器会生成一个包含用户信息的 JWT 令牌,然后将该令牌返回给客户端。如下所示:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.
eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWQiOiIxMjM0NTY3ODkwIiwicm9sZXMiOlsiYWRtaW4iLCJ1c2VyIl19.
SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
- 头部(Header):
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
- alg 参数表示使用的加密算法,这里是 HMAC-SHA256 算法。
- typ 参数表示令牌类型,这里是 JWT。
{
"alg": "HS256",
"typ": "JWT"
}
- 载荷(Payload):
eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWQiOiIxMjM0NTY3ODkwIiwicm9sZXMiOlsiYWRtaW4iLCJ1c2VyIl19
-iss: jwt签发者
-sub: jwt所面向的用户
-aud: 接收jwt的一方
-exp: jwt的过期时间,这个过期时间必须要大于签发时间
-nbf: 定义在什么时间之前,该jwt都是不可用的.
-iat: jwt的签发时间
-jti: jwt的唯一身份标识,主要用来作为一次性token,从而回避重放攻击。
{
"sub": "1234567890",//ID
"name": "John Doe", //角色
"iat": 1516239022 //权限
}
- 签名(Signature):
SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
签名(Signature)部分是对头部和载荷进行数字签名(base64加密)生成的,例如:
HMACSHA256(
base64UrlEncode(header) + "." +
base64UrlEncode(payload),
secret
)
5.3 JWT令牌的基本使用
5.3.1 基本思路
在实际使用中,通常会使用现有的 JWT 库来生成和解析 JWT 令牌,这些库已经实现了 RFC 7519 标准中的格式和规范,因此可以方便地使用这些库来生成和解析 JWT 令牌。本文主要介绍java-jwt,jjwt等这两种库
基本思路:要分为两种页面,登录页面和其他页面,登录页面用于获取token,只有登录了之后才能访问其他页面。登录之后获取到的token会返回给客服端(或者说前端),下一次(其他页面)发起请求时将token添加到请求头,后端设置拦截器判断请求头中的token是否有值(有值就进一步判断值是否正确),如果没有则说明未登录,即没有权限,有值且正确了就放行。值得一提的是登录页面的请求不用拦截,因为需要获取token。通过解析 JWT 令牌并验证签名,可以获取到载荷部分存储的用户的身份和权限,从而判断是否放行。
5.3.2 java-jwt实现JWT
官网:https://github.com/auth0/java-jwt
以下是一个使用 Java 编写的基本 JWT 登录示例,该示例使用 java-jwt库来生成和解析 **JWT **令牌
- 首先,需要在项目中添加 java-jwt依赖
<dependency>
<groupId>com.auth0</groupId>
<artifactId>java-jwt</artifactId>
<version>4.0.0</version> <!--我使用这个版本时报错了-->
<version>3.4.0</version>
</dependency>
- 然后定义一个简单的用户类 User:
@Data
public class User {
private Long id;
private String username;
private String password;
}
- 将JWT主要操作封装
package com.zhaoxi.test.utils;
import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTCreator;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.DecodedJWT;
import org.springframework.stereotype.Component;
import java.util.Calendar;
import java.util.Map;
@Component
public class JwtUtil {
/** 盐值*/
private static final String SING="LIUYISHOU@Token666";
//生成令牌
public static String getToken(Map<String,String> map){
//获取日历对象
Calendar calendar=Calendar.getInstance();
//默认7天过期
calendar.add(Calendar.DATE,7);
//新建一个JWT的Builder对象
JWTCreator.Builder builder = JWT.create();
//将map集合中的数据设置进payload载荷
map.forEach((k,v)->{
builder.withClaim(k, v);
});
//设置过期时间和签名
String sign = builder.withExpiresAt(calendar.getTime()).sign(Algorithm

JWT是一种开放标准,用于安全地在网络应用间传递信息。它由头部、载荷和签名三部分组成,常用于身份验证和授权。本文介绍了JWT的构成、使用方法,并提供了使用java-jwt和jjwt库在Java中生成和验证JWT的示例。
最低0.47元/天 解锁文章
334

被折叠的 条评论
为什么被折叠?



