JWT基础详解

JSON Web Token 简称JWT

一、起源:

这一切的起源都源于网景公司的一个天才程序员,为了解决http协议无状态问题,就让浏览器承担了一部分“记忆”责任(每次客户端,访问服务器,自身就携带cookie,用于表明自身身份)

由于直接在cookie中携带敏感信息,有用户篡改信息、恶意盗取的安全风险。于是有些公司决定将信息统一管理,只是给用户一个”session_id”,标识自己的身份。下次客户端通过cookie携带这个标识去访问服务器时,服务器能通过该标识作为索引查到用户存在服务器中的信息。

由于这种统一式管理,会压榨服务器的性能。为了给服务器减负,token就应运而生。将相关数据加密签名之后,继续发回客户端。也摆脱了用户篡改信息的可能。

但由于加密算法没有统一,这时jwt就作为一种标准(统一了token格式与验证规则),出来统一了token的江湖,他的作用就像restful规范了API设计一样,让不同系统都能更加顺畅的理解和使用token。

--由多篇cookie、token、restful、jwt博客、视频总结而来

二、定义:

1、跨域认证问题

在互联网早期,传递认证信息的方式大都如下:

1、用户向服务器发送用户名和密码。
2、服务器验证通过后,在当前对话(session)里面保存相关数据,比如用户信息。
3、服务器向用户返回一个 session_id,写入用户的 Cookie。
4、用户随后的每一次请求,都会通过 Cookie,将 session_id 传回服务器。
5、服务器收到 session_id,找到前期保存的数据,由此得知用户的身份。

问题: 用户少或者是单机,还能应付过来,若是用户多了,需要多安装几台服务器。就需要持久化层(常见的就是数据库)优点是结构清晰,缺点是工程量大,并且持久层一挂,访问全都变成500了。
最最最重要的是,如果你想要去访问一家公司下的其他网站,由于cookie默认不能跨域,

所以就产生了另一种新思路:

2、JWT原理

另一种方案是服务器索性不保存 session 数据了,所有数据都保存在客户端,每次请求都发回服务器。JWT 就是这种方案的一个代表。

JWT 的原理是,服务器认证以后,生成一个 JSON 对象,发回给用户,就像下面这样。

用户与服务器通讯时,都需要发回这个json对象。
为了防止用户篡改数据,服务器在生成这个对象的时候,会加上签名(后方会详细解释)
此时服务器就不再改变session数据了。(服务器变为了无状态)

3、JWT数据结构

实际上,交互时传递的JWT,长的是这个样子:

它是一个很长的字符串,中间用点(.)分隔成三个部分。(注意jwt是不换行的,这里是方便演示

JWT的3部分如下:

官网介绍:https://jwt.io/introduction 

咱们接下来,详细介绍一下jwt的3个部分

Header

Header 部分是一个 JSON 对象,描述 JWT 的元数据,通常是下面的样子。

alg(algorithm):算法(HS256
typ(type):这个令牌的类型(JWT
最后将上面的JSON对象使用Base64URL算法加密转化成字符串

Payload

Payload 部分也是一个 JSON 对象,用来存放实际需要传递的数据。JWT 规定了7个官方字段,供选用。

当然你也可以自定义一些:

Signature

这部分通常放置的是一个密钥,这个密钥只有服务器才知道,不能泄露给用户。

然后,使用 Header 里面指定的签名算法(默认是 HMAC SHA256),按照下面的公式产生签名。

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

最后JWT是用如下方式生成:

JWT = base64UrlEncode(header) + "."+ base64UrlEncode(payload) + "."+ 
HMACSHA256( base64UrlEncode(header) + "." + base64UrlEncode(payload), secret) 
// 分别对header与payload进行base64url转义编码
// 最后用secret为密钥,通过256算法加密签名

4、JWT使用方法

客户端收到服务器返回的 JWT,可以储存在 Cookie 里面,也可以储存在 localStorage。

此后,客户端每次与服务器通信,都要带上这个 JWT。你可以把它放在 Cookie 里面自动发送,但是这样不能跨域,所以更好的做法是放在 HTTP 请求的头信息Authorization字段里面。
通过如下方式存储:

前端可以这样调用:

另一种做法是,跨域的时候,JWT 就放在 POST 请求的数据体里面。

5、JWT特点

1、JWT 默认是不加密,但也是可以加密的。生成原始 Token 以后,可以用密钥再加密一次。 (不加密的情况下,不能写私密信息)

2、JWT 不仅可以用于认证,也可以用于交换信息。有效使用 JWT,可以降低服务器查询数据库的次数。

3、不可变性(不同角度--优缺点),JWT一但签发,不到期之前就不能修改信息(因为服务器不保存session),除非提前安置好了其他手段

4、JWT包含了认证信息,一旦泄露,任何人都可以获得该令牌的所有权限。为减少盗用,JWT的有效期应该设置的短些。

5、为了减少盗用,jwt不应该使用HTTP协议明码传输,要使用HTTPS协议传输。

三、应用:

不同的语言,有不同的解决方法。

我这里拿go语言举例说明:

1、创建认证结构体与jwt声明结构体

var jwtKey = []byte("my_secret_key") // 自己生成的密钥
// Credentials 用户凭证结构体
type Credentials struct {Username string `json:"username"`Password string `json:"password"`
}// Claims JWT声明结构体
type Claims struct {Username             string `json:"username"`jwt.RegisteredClaims        // 注册表
}

2、创建登入函数,并创建jwt令牌

// loginHandler 处理登入函数
func loginHandler(w http.ResponseWriter, r *http.Request) {// 这里简化了验证creds := Credentials{Username: "123", //r.FormValue("username"),Password: "123", //r.FormValue("password"),}// 实例验证// 创建jwt声明// 是的,创建jwtexpirationTime := time.Now().Add(5 * time.Minute)claims := &Claims{ // 集合sUsername: creds.Username,RegisteredClaims: jwt.RegisteredClaims{ExpiresAt: jwt.NewNumericDate(expirationTime),},}// 生成JWT令牌token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)tokenString, err := token.SignedString(jwtKey)if err != nil {// 过程}// 可以通过cookie携带http.SetCookie(w, &http.Cookie{Name:  "jwt_token",Value: tokenString,// 可选:加 HttpOnly、Secure 等HttpOnly: true,Secure:   true, // 生产环境建议开})// 也可以直接返回Token给客户端 (实际应用应为HttpOnly Cookie)w.Write([]byte(tokenString))}

3、中间件验证,并获取令牌

// JWT认证中间件
func authMiddleware(next http.HandlerFunc) http.HandlerFunc {return func(w http.ResponseWriter, r *http.Request) {// 从Authorization头获取tokenauthHeader := r.Header.Get("Authorization")if authHeader == "" {w.WriteHeader(http.StatusUnauthorized)fmt.Fprint(w, "Missing authorization header")return}// 验证Bearer格式tokenString := authHeader[len("Bearer "):]claims := &Claims{}// 解析并验证Tokentoken, err := jwt.ParseWithClaims(tokenString, claims, func(token *jwt.Token) (interface{}, error) {return jwtKey, nil})if err != nil || !token.Valid {w.WriteHeader(http.StatusUnauthorized)fmt.Fprintf(w, "Invalid token: %v", err)return}// 将声明信息存入请求上下文ctx := context.WithValue(r.Context(), "claims", claims)next.ServeHTTP(w, r.WithContext(ctx))}
}

 4、获取令牌信息

func protectedHandler(w http.ResponseWriter, r *http.Request) {// 从上下文中获取用户名claims, ok := r.Context().Value("claims").(*Claims)if !ok {w.WriteHeader(http.StatusUnauthorized)return}fmt.Fprintf(w, "欢迎访问受保护页面, %s!", claims.Username)
}

 5、注册路由

func main() {// 注册路由http.HandleFunc("/login", loginHandler)http.HandleFunc("/protected", authMiddleware(protectedHandler))fmt.Println("http://localhost:8080//login")http.ListenAndServe(":8080", nil)
}

四、替换方案

大多技术,并非不可替代。一招吃遍天下鲜,往往是不妥当的
在什么样的场景更适合用哪一种技术这样的眼光看待问题,将会更加妥当。

下方是我搜集来的资料,可做了解

OAuth2.0: 

OAuth 2.0 优点:支持第三方授权,保护用户隐私安全;有多种授权模式,适配不同场景,灵活度高;互联网广泛应用,大厂支持,便于开发第三方登录。

OAuth 2.0 缺点:协议复杂,开发者难理解实现,易安全配置不当;授权服务器防护差易致令牌泄露,不同模式也有安全风险 。

SAML:

SAML 优点:支持企业级 SSO,跨安全域传递身份权限,实现单点登录;是开放标准协议,兼容性、互操作性好;支持数字签名与加密,保障身份信息安全。

SAML 缺点:基于 XML,消息冗长,配置维护复杂,需专业知识;XML 解析开销大,大量请求影响性能;企业部署要调整网络、安全策略,成本高 。


借鉴资料:

1、jwt官网 

2、JSON Web Token 入门教程


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/bicheng/89236.shtml
繁体地址,请注明出处:http://hk.pswp.cn/bicheng/89236.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Unity】MiniGame编辑器小游戏(十四)基础支持模块(游戏窗口、游戏对象、物理系统、动画系统、射线检测)

更新日期:2025年7月15日。 项目源码:获取项目源码 索引 基础支持模块一、游戏窗口 MiniGameWindow1.窗体属性2.快速退出键3.模拟帧间隔时间4.生命周期函数5.游戏状态二、游戏对象 MiniGameObject1.位置2.激活状态3.碰撞器4.限制游戏对象的位置5.生命周期函数6.移动三、物理系…

Swift6.0 - 5、基本运算符

目录1、术语2、赋值运算符(a b)3、算术运算符(、-、*、/)3.1、余数运算符(%)3.2、一元负号运算符(-a)3.3、一元正号运算符(a)4、复合赋值运算符(…

DataWhale AI夏令营 Task2.2笔记

本次代码改进主要集中在聚类算法和主题词提取方法的优化上,主要包含三个关键修改:首先,将聚类算法从KMeans替换为DBSCAN。这是因为原KMeans方法需要预先指定聚类数量,而实际评论数据中的主题分布难以预测。DBSCAN算法能够自动确定…

自启动策略调研

广播拦截策略1.流程图广播发送├─ 特权进程(Root/Shell) → 放行├─ 系统进程(UID≤1000) → 自动启动校验 → 非法广播? → 拦截│ ├─ 黑名单匹配 → 拦截│ └─ 用户/白名单校验 → 受限用户? →…

MFC/C++语言怎么比较CString类型最后一个字符

文章目录🔧 1. 直接下标访问(高效首选)🔍 2. ReverseFind 反向定位(语义明确)✂️ 3. Right 提取子串(需临时对象)⚙️ 4. 封装工具函数(推荐健壮性场景)⚠️…

【Cortex-M】异常中断时的程序运行指针SP获取,及SCB寄存器错误类型获取

【Cortex-M】异常中断时的程序运行指针SP获取,及SCB寄存器错误类型获取 更新以gitee为准: gitee 文章目录异常中断异常的程序运行指针SP获取SCB寄存器错误类型获取硬件错误异常 Hard fault status register (SCB->HFSR)存储器管理错误异常 SCB->C…

项目流程管理系统使用建议:推荐13款

本文分享了13款主流的项目流程管理系统,包括:1.PingCode;2.Worktile;3.泛微 E-Office;4.Microsoft Project;5.简道云;6.Zoho Projects;7.Tita 项目管理;8.Oracle Primave…

neovim的文件结构

在 Linux 系统中,Neovim 的配置文件主要存放在以下目录结构中: 📁 核心配置目录路径内容描述~/.config/nvim/主配置目录 (Neovim 的标准配置位置)~/.local/share/nvim/Neovim 运行时数据(插件、会话等) 🗂️…

【网易云-header】

网易云静态页面&#xff08;1&#xff09;效果htmlcss效果 html <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0">&…

Android开发知识点总结合集

初级安卓开发需要掌握的知识点主要包括安卓四大组件、Context、Intent、Handler、Fragment、HandlerThread、AsyncTask、IntentService、Binder、AIDL、SharedPreferences、Activity、Window、DecorView以及ViewRoot层级关系、触摸事件分发机制、View绘制流程、自定义View。 1…

如何通过域名白名单​OVP防盗链加密视频?

文章目录前言一、什么是域名白名单​OVP防盗链二、域名白名单​OVP防盗链的实现原理三、如何实现域名白名单​OVP防盗链加密视频总结前言 用户原创视频资源面临被非法盗链、恶意嵌入的严峻挑战&#xff0c;盗用行为不仅侵蚀创作者收益&#xff0c;更扰乱平台生态秩序。域名白名…

密码学系列文(2)--流密码

一、流密码的基本概念RC4&#xff08;Rivest Cipher 4&#xff09;是由密码学家 Ron Rivest&#xff08;RSA 算法发明者之一&#xff09;于 1987 年设计的对称流加密算法。它以简单、高效著称&#xff0c;曾广泛应用于网络安全协议&#xff08;如 SSL/TLS、WEP/WPA&#xff09;…

Drools‌业务引擎

drools引擎使用 官网介绍 一、底层原理 ReteOO 网络 • 本质是一张“有向无环图”&#xff0c;节点类型&#xff1a; – Root / ObjectTypeNode&#xff1a;按 Java 类型分发事实 – AlphaNode&#xff1a;单对象约束&#xff08;age > 18&#xff09; – BetaNode&#xf…

linux的磁盘满了清理办法

今天测试系统的某个磁盘满了&#xff0c;需要看一下&#xff0c;可以看到的是&#xff0c;已经被占用百分之百了&#xff0c;某些服务运行不了了&#xff0c;需要清一下&#xff0c;这个我熟看哪个目录占用空间大cd / du -sh * ##找到占用最大&#xff0c;比如cd /home cd /hom…

阿里开源项目 XRender:全面解析与核心工具分类介绍

阿里开源项目 XRender&#xff1a;全面解析与核心工具分类介绍 在开源技术飞速发展的浪潮中&#xff0c;阿里巴巴推出的 XRender 作为专注于表单与数据可视化的开源框架&#xff0c;凭借独特的设计理念和强大功能&#xff0c;已在开发者群体中崭露头角。XRender 以 “协议驱动…

网络安全初级--搭建

一、Docker搭建apt-get install docker.io docker-compose 下载docker 配置docker代理 a.创建对应的以及对应的文件mkdir /etc/systemd/system/docker.service.dvim /etc/systemd/system/docker.service.d/http-proxy.confb.写入以下内容[Service]Environment"HTTP_PROXYh…

文心一言4.5深度评测:国产大模型的崛起之路

在⼤语⾔模型竞争⽇益激烈的今天&#xff0c;百度推出的文⼼⼀⾔4.5凭借其在中文处理上的独特优势&#xff0c;正在成为越来越 多开发者的选择。经过为期⼀周的深度测试和数据分析&#xff0c;我将从技术参数、性能表现、成本效益等多个维度&#xff0c; 为⼤家呈现这款国产⼤模…

科技的成就(六十九)

631、摄影术的先驱 1801年&#xff0c;德国物理学家约翰威廉里特&#xff08;Johann Wilhelm Ritter&#xff09;发现了紫外线。他注意到&#xff0c;太阳光谱中紫色一侧光谱之外的位置的不可见射线比紫光更快地使氯化银试剂变暗&#xff0c;他将其称为“化学射线”。后来这种射…

用Golang gRPC异步处理:释放并发性能的秘密武器

目录 章节一:为什么gRPC异步处理是并发性能的“加速器” 异步的本质:解放Goroutine的潜能 异步gRPC的适用场景 章节二:从零开始:搭建一个异步gRPC服务 准备工作:定义Protobuf 实现同步gRPC服务 迈向异步:初步改造 章节三:用Worker Pool模式榨干并发性能 Worker …

MCP终极篇!MCP Web Chat项目实战分享

目录 前言 MCP Web Chat 功能概要说明 MCP Web Chat代码调用结构说明 api动态生成MCP Server 方法一&#xff08;之前的方法&#xff09; 方法二&#xff08;现在的方法&#xff09; 做个比较 相关代码 相关问题解决说明 稳定性 由此引申而来的异步任务问题 MCP周…