您当前的位置:首页 > 电脑百科 > 程序开发 > 编程百科

什么是JWT?为什么要用JWT?

时间:2023-12-06 13:44:32  来源:微信公众号  作者:Java中文社群

目前传统的后台管理系统,以及不使用第三方登录的系统,使用 JWT 技术的还是挺多的,因此在面试中被问到的频率也比较高,所以今天我们就来看一下:什么是 JWT?为什么要用 JWT?

1.什么是 JWT?

JWT(JSON Web Token)是一种开放标准(RFC 7519),用于在网络上安全传输信息的简洁、自包含的方式。它通常被用于身份验证和授权机制。JWT 由三部分组成:头部(Header)、载荷(Payload)和签名(Signature)。

  1. 头部(Header):包含了关于生成该 JWT 的信息以及所使用的算法类型。
  2. 载荷(Payload):包含了要传递的数据,例如身份信息和其他附属数据。JWT 官方规定了 7 个字段,可供使用:
    1. iss (Issuer):签发者。
    2. sub (Subject):主题。
    3. aud (Audience):接收者。
    4. exp (Expiration time):过期时间。
    5. nbf (Not Before):生效时间。
    6. iat (Issued At):签发时间。
    7. jti (JWT ID):编号。
  3. 签名(Signature):使用密钥对头部和载荷进行签名,以验证其完整性。

JWT 官网:https://jwt.io/

2.为什么要用 JWT?

JWT 相较于传统的基于会话(Session)的认证机制,具有以下优势:

  1. 无需服务器存储状态:传统的基于会话的认证机制需要服务器在会话中存储用户的状态信息,包括用户的登录状态、权限等。而使用 JWT,服务器无需存储任何会话状态信息,所有的认证和授权信息都包含在 JWT 中,使得系统可以更容易地进行水平扩展。
  2. 跨域支持:由于 JWT 包含了完整的认证和授权信息,因此可以轻松地在多个域之间进行传递和使用,实现跨域授权。
  3. 适应微服务架构:在微服务架构中,很多服务是独立部署并且可以横向扩展的,这就需要保证认证和授权的无状态性。使用 JWT 可以满足这种需求,每次请求携带 JWT 即可实现认证和授权。
  4. 自包含:JWT 包含了认证和授权信息,以及其他自定义的声明,这些信息都被编码在 JWT 中,在服务端解码后使用。JWT 的自包含性减少了对服务端资源的依赖,并提供了统一的安全机制。
  5. 扩展性:JWT 可以被扩展和定制,可以按照需求添加自定义的声明和数据,灵活性更高。

总结来说,使用 JWT 相较于传统的基于会话的认证机制,可以减少服务器存储开销和管理复杂性,实现跨域支持和水平扩展,并且更适应无状态和微服务架构。

3.JWT 基本使用

JAVA 开发中,可以借助 JWT 工具类来方便的操作 JWT,例如 HuTool 框架中的 JWTUtil。

HuTool 介绍:https://doc.hutool.cn/pages/JWTUtil/

使用 HuTool 操作 JWT 的步骤如下:

  1. 添加 HuTool 框架依赖
  2. 生成 Token
  3. 验证和解析 Token

3.1 添加 HuTool 框架依赖

在 pom.xml 中添加以下信息:

<dependency>
    <groupId>cn.hutool</groupId>
    <artifactId>hutool-all</artifactId>
    <version>5.8.16</version>
</dependency>

3.2 生成 Token

Map<String, Object> map = new HashMap<String, Object>() {
private static final long serialVersionUID = 1L;
{
    put("uid", Integer.parseInt("123")); // 用户ID
    put("expire_time", System.currentTimeMillis() + 1000 * 60 * 60 * 24 * 15); // 过期时间15天
}
};
JWTUtil.createToken(map, "服务器端秘钥".getBytes());

3.3 验证和解析 Token

验证 Token 的示例代码如下:

String token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX25hbWUiOiJhZG1pbiIsInNjb3BlIjpbImFsbCJdLCJleHAIOjE2MjQwMDQ4MjIsInVzZXJJZCI6MSwiYXV0aG9yaXRpZXMiOlsiUk9MRV_op5LoibLkuozlj7ciLCJzeXNfbWVudV8xIiwiUk9MRV_op5LoibLkuIDlj7ciLCJzeXNfbWVudV8yIl0sImp0aSI6ImQ0YzVlYjgwLTA5ZTctNGU0ZC1hZTg3LTVkNGI5M2FhNmFiNiIsImNsaWVudF9pZCI6ImhhbmR5LXNob3AifQ.aixF1eKlAKS_k3ynFnStE7-IRGiD5YaqznvK2xEjBew";
JWTUtil.verify(token, "123456".getBytes());

解析 Token 的示例代码如下:

String rightToken = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwiYWRtaW4iOnRydWUsIm5hbWUiOiJsb29seSJ9.U2aQkC2THYV9L0fTN-yBBI7gmo5xhmvMhATtu8v0zEA";
final JWT jwt = JWTUtil.parseToken(rightToken);
jwt.getHeader(JWTHeader.TYPE);
jwt.getPayload("sub");

3.4 代码实战

在登录成功之后,生成 Token 的示例代码如下:

// 登录成功,使用 JWT 生成 Token
Map<String, Object> payload = new HashMap<String, Object>() {
    private static final long serialVersionUID = 1L;
    {
        put("uid", userinfo.getUid());
        put("manager", userinfo.getManager());
        // JWT 过期时间为 15 天
        put("exp", System.currentTimeMillis() + 1000 * 60 * 60 * 24 * 15);
    }
};
String token = JWTUtil.createToken(payload, AppVariable.JWT_KEY.getBytes());

例如在 Spring Cloud Gateway 网关中验证 Token 的实现代码如下:

import cn.hutool.jwt.JWT;
import cn.hutool.jwt.JWTUtil;
import com.example.common.AppVariable;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.util.List;

/**
 * 登录过滤器(登录判断)
 */
@Component
public class AuthFilter implements GlobalFilter, Ordered {
    // 排除登录验证的 URL 地址
    private String[] skipAuthUrls = {"/user/add", "/user/login"};

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        // 当前请求的 URL
        String url = exchange.getRequest().getURI().getPath();
        for (String item : skipAuthUrls) {
            if (item.equals(url)) {
                // 继续往下走
                return chain.filter(exchange);
            }
        }
        ServerHttpResponse response = exchange.getResponse();
        // 登录判断
        List<String> tokens =
                exchange.getRequest().getHeaders().get(AppVariable.TOKEN_KEY);
        if (tokens == null || tokens.size() == 0) {
            // 当前未登录
            response.setStatusCode(HttpStatus.UNAUTHORIZED);
            return response.setComplete();
        }
        // token 有值
        String token = tokens.get(0);
        // JWT 效验 token 是否有效
        boolean result = false;
        try {
            result = JWTUtil.verify(token, AppVariable.JWT_KEY.getBytes());
        } catch (Exception e) {
            result = false;
        }
        if (!result) {
            // 无效 token
            response.setStatusCode(HttpStatus.UNAUTHORIZED);
            return response.setComplete();
        } else { // 判断 token 是否过期
            final JWT jwt = JWTUtil.parseToken(token);
            // 得到过期时间
            Object expObj = jwt.getPayload("exp");
            if (expObj == null) {
                response.setStatusCode(HttpStatus.UNAUTHORIZED);
                return response.setComplete();
            }
            long exp = Long.parseLong(expObj.toString());
            if (System.currentTimeMillis() > exp) {
                // token 过期
                response.setStatusCode(HttpStatus.UNAUTHORIZED);
                return response.setComplete();
            }
        }
        return chain.filter(exchange);
    }

    @Override
    public int getOrder() {
        // 值越小越早执行
        return 1;
    }
}

4.实现原理分析

JWT 本质是将秘钥存放在服务器端,并通过某种加密手段进行加密和验证的机制。加密签名=某加密算法(header+payload+服务器端私钥),因为服务端私钥别人不能获取,所以 JWT 能保证自身其安全性。

小结

JWT 相比与传统的 Session 会话机制,具备无状态性(无需服务器端存储会话信息),并且它更加灵活、更适合微服务环境下的登录和授权判断。JWT 是由三部分组成的:Header(头部)、Payload(数据载荷)和 Signature(签名)。


Tags:JWT   点击:()  评论:()
声明:本站部分内容及图片来自互联网,转载是出于传递更多信息之目的,内容观点仅代表作者本人,不构成投资建议。投资者据此操作,风险自担。如有任何标注错误或版权侵犯请与我们联系,我们将及时更正、删除。
▌相关推荐
什么是JWT?为什么要用JWT?
目前传统的后台管理系统,以及不使用第三方登录的系统,使用 JWT 技术的还是挺多的,因此在面试中被问到的频率也比较高,所以今天我们就来看一下:什么是 JWT?为什么要用 JWT?1.什么是...【详细内容】
2023-12-06  Search: JWT  点击:(170)  评论:(0)  加入收藏
jwt与token+redis,哪种方案更好用?
在选择 JWT 与 Token+Redis 时,系统的具体需求和设计目标将是决定性因素。这两种方案都有各自的优缺点,适用于不同的场景。JWT 方案: 优点:无状态性:后端不需要存储 Token,减轻了...【详细内容】
2023-12-03  Search: JWT  点击:(18)  评论:(0)  加入收藏
Go语言中如何实现JWT
什么JWTJWT(JSON Web Token)是一种开放标准(RFC 7519),定义了一种在各方之间安全传输信息的简洁方式。这些信息可以被验证和信任,因为它们是数字签名的。JWT由三部分组成,用.分隔。...【详细内容】
2023-09-11  Search: JWT  点击:(250)  评论:(0)  加入收藏
基于JWT的RuoYi开发框架与EMQX的系统集成方法
我们使用JwtAccessTokenConverter来生成Jwt Token,JwtAccessTokenConverter默认使用的Signer是MacSigner,而MacSigner默认的算法是HMACSHA256。下面这个地方配置的Signkey一...【详细内容】
2023-05-17  Search: JWT  点击:(95)  评论:(0)  加入收藏
使用passport.js 的 google auth 2.0 的 JWT 身份验证
第 1 步:创建您的初始node.js 应用程序并安装以下包,因为我们将在我们的项目中使用它npm i express,jsonwebtoken,passport,passport-google-oauth20,dotenv第 2 步:在 google...【详细内容】
2023-02-07  Search: JWT  点击:(321)  评论:(0)  加入收藏
Node.JS基础库JWT爆发严重RCE漏洞
近日著名node.js库JWT(JsonWebToken )被爆存在严重远程漏洞。作为一个基础库,JWT被供应链广泛采用用,影响22000 多个项目个项目,其中包括Microsoft、Twilio、Salesforce、Intuit...【详细内容】
2023-01-12  Search: JWT  点击:(276)  评论:(0)  加入收藏
SpringBoot整合JWT实现登录认证
1、JWT的构成- 头部(header):描述该JWT的最基本的信息,如类型以及签名所用的算法。- 负载(payload):存放有效信息的地方。- 签证(signature):base64加密后的header、base64加...【详细内容】
2022-07-08  Search: JWT  点击:(267)  评论:(0)  加入收藏
ASP.NET Core 6.0 添加 JWT 认证和授权
序言本文将分别介绍 Authentication(认证) 和 Authorization(授权)。并以简单的例子在 ASP.NET Core 6.0 的 WebAPI 中分别实现这两个功能。 相关名词Authentication 和 Author...【详细内容】
2022-04-18  Search: JWT  点击:(751)  评论:(0)  加入收藏
不懂就学,什么是JWT?
文章已收录到我的Github精选,欢迎Star:https://github.com/yehongzhi/learningSummary起源需要了解一门技术,首先从为什么产生开始说起是最好的。JWT主要用于用户登录鉴权,所以...【详细内容】
2021-12-07  Search: JWT  点击:(278)  评论:(0)  加入收藏
前端鉴权的兄弟们:cookie、session、token、jwt、单点登录
从状态说起原文:「链接」我们知道,HTTP 是无状态的。也就是说,HTTP 请求方和响应方之间无法维护状态,都是一次性的,它不知道前后的请求都发生了什么。但有的场景下,我们需要维护状...【详细内容】
2021-07-29  Search: JWT  点击:(722)  评论:(0)  加入收藏
▌简易百科推荐
即将过时的 5 种软件开发技能!
作者 | Eran Yahav编译 | 言征出品 | 51CTO技术栈(微信号:blog51cto) 时至今日,AI编码工具已经进化到足够强大了吗?这未必好回答,但从2023 年 Stack Overflow 上的调查数据来看,44%...【详细内容】
2024-04-03    51CTO  Tags:软件开发   点击:(5)  评论:(0)  加入收藏
跳转链接代码怎么写?
在网页开发中,跳转链接是一项常见的功能。然而,对于非技术人员来说,编写跳转链接代码可能会显得有些困难。不用担心!我们可以借助外链平台来简化操作,即使没有编程经验,也能轻松实...【详细内容】
2024-03-27  蓝色天纪    Tags:跳转链接   点击:(12)  评论:(0)  加入收藏
中台亡了,问题到底出在哪里?
曾几何时,中台一度被当做“变革灵药”,嫁接在“前台作战单元”和“后台资源部门”之间,实现企业各业务线的“打通”和全域业务能力集成,提高开发和服务效率。但在中台如火如荼之...【详细内容】
2024-03-27  dbaplus社群    Tags:中台   点击:(8)  评论:(0)  加入收藏
员工写了个比删库更可怕的Bug!
想必大家都听说过删库跑路吧,我之前一直把它当一个段子来看。可万万没想到,就在昨天,我们公司的某位员工,竟然写了一个比删库更可怕的 Bug!给大家分享一下(不是公开处刑),希望朋友们...【详细内容】
2024-03-26  dbaplus社群    Tags:Bug   点击:(5)  评论:(0)  加入收藏
我们一起聊聊什么是正向代理和反向代理
从字面意思上看,代理就是代替处理的意思,一个对象有能力代替另一个对象处理某一件事。代理,这个词在我们的日常生活中也不陌生,比如在购物、旅游等场景中,我们经常会委托别人代替...【详细内容】
2024-03-26  萤火架构  微信公众号  Tags:正向代理   点击:(10)  评论:(0)  加入收藏
看一遍就理解:IO模型详解
前言大家好,我是程序员田螺。今天我们一起来学习IO模型。在本文开始前呢,先问问大家几个问题哈~什么是IO呢?什么是阻塞非阻塞IO?什么是同步异步IO?什么是IO多路复用?select/epoll...【详细内容】
2024-03-26  捡田螺的小男孩  微信公众号  Tags:IO模型   点击:(8)  评论:(0)  加入收藏
为什么都说 HashMap 是线程不安全的?
做Java开发的人,应该都用过 HashMap 这种集合。今天就和大家来聊聊,为什么 HashMap 是线程不安全的。1.HashMap 数据结构简单来说,HashMap 基于哈希表实现。它使用键的哈希码来...【详细内容】
2024-03-22  Java技术指北  微信公众号  Tags:HashMap   点击:(11)  评论:(0)  加入收藏
如何从头开始编写LoRA代码,这有一份教程
选自 lightning.ai作者:Sebastian Raschka机器之心编译编辑:陈萍作者表示:在各种有效的 LLM 微调方法中,LoRA 仍然是他的首选。LoRA(Low-Rank Adaptation)作为一种用于微调 LLM(大...【详细内容】
2024-03-21  机器之心Pro    Tags:LoRA   点击:(12)  评论:(0)  加入收藏
这样搭建日志中心,传统的ELK就扔了吧!
最近客户有个新需求,就是想查看网站的访问情况。由于网站没有做google的统计和百度的统计,所以访问情况,只能通过日志查看,通过脚本的形式给客户导出也不太实际,给客户写个简单的...【详细内容】
2024-03-20  dbaplus社群    Tags:日志   点击:(4)  评论:(0)  加入收藏
Kubernetes 究竟有没有 LTS?
从一个有趣的问题引出很多人都在关注的 Kubernetes LTS 的问题。有趣的问题2019 年,一个名为 apiserver LoopbackClient Server cert expired after 1 year[1] 的 issue 中提...【详细内容】
2024-03-15  云原生散修  微信公众号  Tags:Kubernetes   点击:(5)  评论:(0)  加入收藏
站内最新
站内热门
站内头条