JWT详解与基本使用(保姆教程)
前言: 最近准备写一篇关于security前后端分离场景下的认证与授权文章,里面使用到了jwt,所以就写了一篇jwt的文章,作为开头小菜😋
概述
讲jwt之前,先讲一下什么是token?
token其实就是服务端在用户认证成功(登陆成功)之后生成的一串加密字符串,用户每次发送请求 请求后端资源时也发送给服务端,从而验证用户身份的合法地位(即你是谁,有没有资格访问),允许用户访问该令牌允许的路由、服务和资源等,所以说token的主要作用就是用户授权,如下图
什么是jwt?
jwt就是JSON Web Token,他是一种使用密钥(使用 HMAC 算法)或使用 RSA 或 ECDSA 的公钥/私钥对进行加密的token,也是目前最常用的一种token
构成
jwt由三部分组成,分别是header(头部)、payload(有效载荷)、signature(签名)组成,用 . 进行连接,所以token(代指JWT)通常的格式是 : aaa.bbb.ccc
Header
头部通常由两部分组成:令牌的类型(即 JWT)和正在使用的签名算法(如 HMAC SHA256 或 RSA),例如:
{
"typ": "JWT" ,
"alg": "HS256"
}
然后此 JSON 被 Base64Url 编码形成 JWT 的第一部分
另外,常用的签名算法还有:
HS256 HS384 HS512 PS256 PS384 PS512 RS256 RS384 RS512 ES256 ES256K 等,大家根据自己习惯选择签名算法(这个影响不大)
算法原理啥的就不说了,大家有兴趣自己去百度😊
Payload
payload谷歌翻译为有效载荷,但我觉得其实就是内容的意思,我们可以把想要存的一些信息以json字符串的形式存储在这里。比如用户id等用户信息。同时还可以存放iss(颁发者),exp(到期时间)等声明(详情可以查看官方文档)。例如:
{
"id":1,
"username" : "mango",
"exp":"1664812343"
}
然后此json也会被 Base64Url 编码形成 JWT 的第二部分
Signature
签名用于验证token在此过程中未被更改,并且对于使用私钥签名的令牌,它还可以验证 JWT 的发送者是否是它所说的人。
通过编码后的header、编码后的payload然后使用header中声明的加密算法进行加盐secret组合加密得到一个字符串,这就是token的第三部分
例如,如果要使用 HMAC SHA256 算法,将按以下方式创建签名:
HMACSHA256(
base64UrlEncode(header) + "." + base64UrlEncode(payload),
secret)
注意: secret是保存在服务端并进行签发的,secret就是用来进行jwt的签发与验证,就是相当于一个密钥,一旦泄露给客户端,意味着客户端也能自我签发jwt
总结
所以jwt除了用于token鉴权以外,还可以进行信息的安全传输,因为通过签名可以确定用户(使用私钥)和防止内容被篡改。(当然缺点就是传输的信息是公开的)
注意:因为token用来加密的算法仅仅是用于加密签名,防止token被篡改,而存储用户信息的payload仅仅是用Base64Url编码而成,其他人可以通过解码获取信息,所以不建议把用户敏感信息(如用户密码)存入token(防止泄漏)😱
token的基本使用
项目依赖,这里使用的是auth0,可以去官网根据自己算法需要选择依赖
<dependency>
<groupId>com.auth0</groupId>
<artifactId>java-jwt</artifactId>
<version>3.18.2</version>
</dependency>
生成token😊
public class Main {
public static void main(String[] args) {
//时间工具类
Calendar instance = Calendar.getInstance();
//设置过期时间 单位:SECOND秒 一个小时失效
instance.add(Calendar.SECOND,60*60);
JWTCreator.Builder builder = JWT.create()
//添加键值对数据
.withClaim("id", 1)
//添加过期时间 exp 也可以添加key为exp valus为到期时间的时间戳和这个效果一样
//.withClaim("exp",1664815770)
.withExpiresAt(instance.getTime());
// 选择签名算法HMAC256 添加密钥字符串mango(盐)
String token = builder.sign(Algorithm.HMAC256("mango"));
//输出token
System.out.println(token);
}
}
验证token并获取数据😱
public class Main {
public static void main(String[] args) {
//验证的token
String token = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY0ODIwMDUzfQ.SNy4Venx_AE8eqow6c3bVNwbmlX7-iz8OiDiPntY6DA";
try{
//提供密钥字符串(盐)和token
DecodedJWT jwt = JWT.require(Algorithm.HMAC256("mango")).build().verify(token);
//输出存储在Payload中键值对key为id的value 即id
System.out.println(jwt.getClaim("id"));
//token设置过期时间就会有key为exp的键值对 value是到期时间的时间戳
System.out.println(jwt.getClaim("exp"));
}catch (TokenExpiredException e){
//令牌过期抛出异常
System.out.println("令牌过期");
}catch (Exception e){
//token非法验证失败抛出异常
System.out.println("检验失败");
}
}
}
这就是token最基本的生成与验证使用,实际使用中一般是集成一个工具类使用。
结语:因为打算写一篇关于security前后端分离场景下的认证与授权文章,其中就是使用security+jwt实现的认证授权,所以就先写一篇有关于jwt的文章,大家要是觉得有用的话点个赞吧😘,下篇见😊
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 【杭电多校比赛记录】2025“钉耙编程”中国大学生算法设计春季联赛(1)