分享一篇详尽的关于如何在 JavaScript 中实现刷新令牌的指南

151ceb72c013f4cc78415edc96b38ea1.jpeg

介绍

刷新令牌允许用户无需重新进行身份验证即可获取新的访问令牌,从而确保更加无缝的身份验证体验。这是通过使用长期刷新令牌来获取新的访问令牌来完成的,即使原始访问令牌已过期也是如此。

通常,当用户登录时,服务器会生成一对令牌:访问令牌和刷新令牌。访问令牌的生命周期很短,用于对用户进行身份验证并授予他们对受保护资源的访问权限。刷新令牌具有较长的生命周期,用于在原始访问令牌过期后获取新的访问令牌。

当访问令牌过期时,客户端将刷新令牌发送到服务器,然后服务器验证刷新令牌并生成新的访问令牌。此过程在后台发生,用户无需重新输入凭据。用户可以不间断地继续访问受保护的资源。这样,用户就不必重复登录,从而实现无缝的身份验证体验。

此外,刷新令牌还为服务器提供了一种撤销用户访问权限的方法,而无需用户重新进行身份验证。通过使刷新令牌无效,服务器可以阻止用户获取新的访问令牌,从而有效地将他们从系统中注销。

总之,刷新令牌是一个强大的工具,可在您的应用程序中维持无缝且安全的身份验证体验。它们允许用户继续访问受保护的资源而无需重新进行身份验证,同时还为服务器提供了一种在必要时撤销访问的方法。

OAuth 2.0 和 JWT

OAuth 2.0 是一种开放的授权标准,使应用程序能够通过授权服务器访问资源服务器(通常是 API)上的资源所有者(通常是用户)的资源。JWT(JSON Web 令牌)是一种紧凑、URL 安全的方式,用于表示要在两方之间传输的声明。

在 OAuth 2.0 中,JWT 可以用作访问令牌和/或刷新令牌。访问令牌用于访问受保护的资源,例如 API,而刷新令牌用于在当前访问令牌过期时获取新的访问令牌。

当 JWT 用作访问令牌时,它通常使用用户的声明和令牌的过期时间进行编码。然后,资源服务器可以解码令牌以验证用户的身份并授权访问受保护的资源。

当 JWT 用作刷新令牌时,它通常使用指示当前访问令牌的过期时间的声明进行编码。当当前访问令牌过期时,客户端可以使用刷新令牌来获取新的访问令牌。

总之,OAuth 2.0 提供了一个用于保护资源访问的框架,而 JWT 提供了一种紧凑且安全的方式来编码和在各方之间传输声明。OAuth 2.0 和 JWT 可以一起用于为 Web 和移动应用程序创建安全高效的授权系统。

JWT 令牌的结构

这是遵循 JWT 格式的解码访问令牌的内容:

{"iss": "https://YOUR_DOMAIN/","sub": "auth0|123456","aud": ["my-api-identifier","https://YOUR_DOMAIN/userinfo"],"azp": "YOUR_CLIENT_ID","exp": 1489179954,"iat": 1489143954,"scope": "openid profile email address phone read:appointments"
}

在其紧凑形式中,JSON Web 令牌由用点 (.) 分隔的三个部分组成,它们是:

  • 标头(Header)

  • 有效载荷(Payload)

  • 签名(Signature)

因此,JWT 通常如下所示。

xxxxx.yyyyy.zzzzz

让我们分解不同的部分。

标头(Header)

标头通常由两部分组成:令牌的类型(JWT)和所使用的签名算法(例如 HMAC SHA256 或 RSA)。

例如:

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

然后,对该 JSON 进行 Base64Url 编码以形成 JWT 的第一部分。

有效载荷(Payload)

令牌的第二部分是有效负载,其中包含声明。声明是关于实体(通常是用户)和附加数据的声明。索赔分为三种类型:注册索赔、公共索赔和私人索赔。

  • 注册声明:这些是一组预定义的声明,不是强制性的,而是推荐的,以提供一组有用的、可互操作的声明。其中一些是:iss(发行者)、exp(到期时间)、sub(主题)、aud(受众)等。

  • 请注意,声明名称只有三个字符长,因为 JWT 旨在紧凑。

  • 公共声明:这些可以由使用 JWT 的人随意定义。但为了避免冲突,它们应该在 IANA JSON Web 令牌注册表中定义,或者定义为包含防冲突命名空间的 URI。

  • 私人声明:这些是为在同意使用它们的各方之间共享信息而创建的自定义声明,既不是注册声明也不是公开声明。

有效负载示例可以是:

{"sub": "1234567890","name": "John Doe","admin": true
}

然后对有效负载进行 Base64Url 编码以形成 JSON Web 令牌的第二部分。

默认支持七个注册声明名称:

iss": (Issuer)声明,"iss"(issuer)声明标识发布JWT的主体。

"exp": (Expiration Time)声明,"exp"(expiration time)声明标识JWT不得在其到期时间之后或之时接受处理。

"sub": (Subject)声明,"sub"(subject)声明标识JWT的主体。

"aud": (Audience)声明,"aud"(audience)声明标识JWT的接收者。

"nbf": (Not Before)声明,"nbf"(not before)声明标识JWT不能在此时间之前接受处理。

"iat": (Issued At)声明,"iat"(issued at)声明标识JWT的发行时间。

"jti": (JWT ID)声明,"jti"(JWT ID)声明为JWT提供唯一标识符。

签名(Signature)

要创建签名部分,您必须获取编码的标头、编码的有效负载、秘密、标头中指定的算法,然后对其进行签名。

例如,如果要使用HMAC SHA256算法,则将通过以下方式创建签名:

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

签名用于验证消息在传输过程中没有发生更改,并且在使用私钥签名的令牌的情况下,它还可以验证 JWT 的发送者是否是其所说的人。

将所有内容放在一起

输出是三个由点分隔的 Base64-URL 字符串,可以在 HTML 和 HTTP 环境中轻松传递,同时与基于 XML 的标准(例如 SAML)相比更加紧凑。这是使用 jwt.io 解码编码令牌的示例。

5447ba992ca5c36433f18bb699ed3ea7.jpeg

实施刷新令牌

请务必记住,OAuth 2.0 规范定义了访问令牌和刷新令牌。因此,如果我们根据其他身份协议或框架(例如 SAML)讨论授权策略,我们将不会有访问令牌或刷新令牌的概念。

以下是应用程序如何在 Node.js 应用程序中使用 JWT 刷新令牌的示例:

  • 用户登录到应用程序并将其凭据发送到身份验证服务器。

  • 身份验证服务器验证凭据,生成 JWT 访问令牌和 JWT 刷新令牌。访问令牌包含用户的声明(例如,用户 ID、角色等),刷新令牌包含指示访问令牌过期时间的声明。

  • 身份验证服务器将访问令牌和刷新令牌发送给客户端。

  • 客户端将令牌存储在本地存储中或作为仅 HTTP 的安全 cookie。

  • 客户端在每个访问受保护资源的请求中发送访问令牌。

  • 当访问令牌过期时,客户端将刷新令牌发送到认证服务器以获取新的访问令牌。

  • 身份验证服务器验证刷新令牌并检查过期时间声明。如果刷新令牌有效且未过期,则身份验证服务器会颁发具有新过期时间的新访问令牌。

  • 身份验证服务器将新的访问令牌发送给客户端。

  • 客户端存储新的访问令牌并继续使用它来访问受保护的资源。

本示例使用 JWT 作为独立的刷新令牌,它可以存储在客户端,可用于跨多个域对用户进行身份验证和授权。

以下代码示例展示了如何在 Python 脚本中使用刷新令牌来确保用户的无缝体验:

4f8ce1ee009c50741fee00b2a497d99b.jpeg

此示例使用 jwt 库来解码 JWT 访问令牌,并使用 requests 库发出 HTTP 请求。该脚本首先向令牌端点发出初始请求以获取访问令牌和刷新令牌。然后,对访问令牌进行解码以获取过期时间,并在向受保护端点发出请求之前检查该过期时间。如果访问令牌已过期,脚本将使用刷新令牌来获取新的访问令牌,然后重试原始请求。

请注意,这是一个简单的示例,在现实场景中,您应该处理错误,并且应该使用为您处理令牌流(例如 pyJWT)的库或框架,并且您不应该对凭证、端点和代码中的secret_key。您还应该使用安全的方式来传输令牌并保证secret_key的安全

使刷新令牌无效

如果刷新令牌遭到泄露,您可以撤销它们。

可以在服务器端通过将令牌添加到黑名单或在数据库中将其标记为已撤销来使刷新令牌失效。以下是如何使用 Node.js 和 MongoDB 使刷新令牌失效的示例:

f62b54de653f165422d63681b46db0f4.jpeg

在此示例中,我们使用 Mongoose 库与 MongoDB 数据库进行交互,并且定义了一个 RefreshToken 模型,该模型映射到数据库中的刷新令牌集合。invalidateRefreshToken函数以token为参数,在数据库中查找对应的刷新token。如果找到令牌,则会将该令牌标记为已撤销并将其保存在数据库中。如果未找到令牌,则返回错误。

这只是一个示例,您可以根据您的堆栈和架构进行调整。需要注意的是,这个例子只是一个服务器端实现,您还需要相应地处理客户端。

还需要注意的是,此示例不适合生产,因为它仅将令牌标记为已撤销,并且不处理令牌黑名单。在生产环境中,建议使用Redis等分布式机制来处理黑名单。

代码示例:客户端使刷新令牌失效

在客户端,可以通过从客户端存储中删除令牌并确保客户端不会再次使用该令牌来使刷新令牌失效。以下是如何使用 JavaScript 使刷新令牌失效的示例:

c9175cd4df2d0401afc91925a6111ebc.jpeg

在此示例中,我们使用 localStorage 对象来存储和检索刷新令牌。调用 invalidateRefreshToken 函数时,它会从客户端存储中检索刷新令牌并将其删除。然后它向服务器发出获取请求以使令牌无效。服务器应该有一个监听此请求的路由,如前面的示例所示。

需要注意的是,此示例使用 localStorage 来存储令牌。您可以使用其他存储方法,例如 sessionStorage 或 cookie。另外,这个示例是为了演示目的而以简单的方式完成的,在生产环境中建议使用 axios 等库来发出 HTTP 请求。

还需要注意的是,这个示例只是一个客户端实现。

总结

总之,实施刷新令牌是在 Web 应用程序中提供无缝、安全的用户体验的关键一步。通过使用刷新令牌,您可以确保用户保持登录状态,同时最大限度地降低安全风险。本文提供的指南(包括如何使用 JavaScript 实现刷新令牌的示例)应该为您重振身份验证过程提供一个良好的起点。

值得注意的是,实施刷新令牌并不是一种万能的解决方案,了解所涉及的权衡非常重要。例如,使用刷新令牌会增加应用程序的复杂性,如果处理不当,还会增加令牌泄露的风险。因此,彻底测试您的实施并留意任何潜在的安全漏洞非常重要。

最后,建议使用为您处理令牌流的库或框架,这可以使实现刷新令牌的过程变得更加容易和安全。使用安全的方式来传输令牌并保证 Secret_key 的安全也很重要。

总的来说,在身份验证过程中加入刷新令牌可以极大地改善用户体验并提高 Web 应用程序的安全性。通过本指南,您现在应该具备在 JavaScript 应用程序中实现刷新令牌所需的知识和工具。

由于文章内容篇幅有限,今天的内容就分享到这里,文章结尾,我想提醒您,文章的创作不易,如果您喜欢我的分享,请别忘了点赞和转发,让更多有需要的人看到。同时,如果您想获取更多前端技术的知识,欢迎关注我,您的支持将是我分享最大的动力。我会持续输出更多内容,敬请期待。

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

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

相关文章

CentOS 8 上安装 Nginx

Nginx是一款高性能的开源Web服务器和反向代理服务器,以其轻量级和高效能而广受欢迎。在本教程中,我们将学习在 CentOS 8 操作系统上安装和配置 Nginx。 步骤 1:更新系统 在安装任何软件之前,让我们先更新系统的软件包列表和已安…

关于提示词 Prompt

Prompt原则 原则1 提供清晰明确的指示 注意在提示词中添加正确的分割符号 prompt """ 请给出下面文本的摘要&#xff1a; <你的文本> """可以指定输出格式&#xff0c;如&#xff1a;Json、HTML提示词中可以提供少量实例&#xff0c;…

大数据面试题:Kafka的单播和多播

面试题来源&#xff1a; 《大数据面试题 V4.0》 大数据面试题V3.0&#xff0c;523道题&#xff0c;679页&#xff0c;46w字 参考答案&#xff1a; 1、单播 一条消息只能被某一个消费者消费的模式称为单播。要实现消息单播&#xff0c;只要让这些消费者属于同一个消费者组即…

nosql之redis集群

文章目录 一.redis集群1.单节点redis服务器带来的问题2.集群redis3.集群的优势4.redis集群的实现方法5.redis群集的三种模式5.1 主从复制5.2 哨兵5.3 集群 二.Redis 主从复制1.主从复制概念2.主从复制的作用3.主从复制流程4.搭建Redis 主从复制4.1 安装 Redis4.2 修改 Redis 配…

【C++学习笔记】extern “c“以及如何查看符号表

如何查看符号表 要查看.a文件的内容&#xff0c;可以使用ar命令。下面是一些常见的用法&#xff1a; 列出.a文件中包含的所有文件&#xff1a; ar t <filename.a>提取.a文件中的单个文件&#xff1a; ar x <filename.a> <filename.o>将.a文件中的所有文件提…

【iToday】涵盖100+技术网站的一站式资讯平台 | 文末送书

里面包含了上百个IT网站&#xff0c;欢迎大家访问&#xff1a;http://itoday.top/#/ iToday&#xff0c;打开信息的新时代。作为一家创新的IT数字媒体平台&#xff0c;iToday致力于为用户提供最新、最全面的IT资讯和内容。里面包含了技术资讯、IT社区、面试求职、前沿科技等诸多…

Python实现GA遗传算法优化循环神经网络回归模型(LSTM回归算法)项目实战

说明&#xff1a;这是一个机器学习实战项目&#xff08;附带数据代码文档视频讲解&#xff09;&#xff0c;如需数据代码文档视频讲解可以直接到文章最后获取。 1.项目背景 遗传算法&#xff08;Genetic Algorithm&#xff0c;GA&#xff09;最早是由美国的 John holland于20世…

【学习笔记】关于RAW图片的概念学习

这里是尼德兰的喵芯片设计相关文章&#xff0c;欢迎您的访问&#xff01; 如果文章对您有所帮助&#xff0c;期待您的点赞收藏&#xff01; 让我们一起为成为芯片前端全栈工程师而努力&#xff01; 前言 能为我介绍一下raw图片吗&#xff1f; 当谈论"Raw图片"时&am…

019 - STM32学习笔记 - Fatfs文件系统(一) - FatFs文件系统初识

019 - STM32学习笔记 - Fatfs文件系统&#xff08;一&#xff09; - FatFs文件系统初识 最近工作比较忙&#xff0c;没时间摸鱼学习&#xff0c;抽空学点就整理一点笔记。 1、文件系统 在之前学习Flash的时候&#xff0c;可以调用SPI_FLASH_BufferWrite函数&#xff0c;将数…

Windows 11 上使用 Docker 安装 SQL Server 2022 数据库

Windows 11 上使用 Docker 安装 SQL Server 2022 数据库&#xff0c;你可以按照以下步骤进行操作&#xff1a; 安装 Docker Desktop for Windows&#xff1a; 访问 Docker 官方网站&#xff08;https://www.docker.com/get-started&#xff09;下载并安装适用于 Windows 的 Do…

“RWEQ+”集成技术在土壤风蚀模拟与风蚀模数估算、变化归因分析中的实践应用及SCI论文撰写

土壤风蚀是一个全球性的环境问题。中国是世界上受土壤风蚀危害最严重的国家之一&#xff0c;土壤风蚀是中国干旱、半干旱及部分湿润地区土地荒漠化的首要过程。中国风蚀荒漠化面积达160.74104km2&#xff0c;占国土总面积的16.7%&#xff0c;严重影响这些地区的资源开发和社会经…

SpringBoot原理分析 | 安全框架:Shiro

&#x1f497;wei_shuo的个人主页 &#x1f4ab;wei_shuo的学习社区 &#x1f310;Hello World &#xff01; Shiro Shiro是一个安全框架&#xff0c;用于认证、授权和管理应用程序的安全性。它提供了一组易于使用的API和工具&#xff0c;可以帮助您轻松地添加安全性到您的应用…

2.10 Android ebpf帮助函数解读(九)

161.struct task_struct *bpf_get_current_task_btf(void) 描述:返回一个指向"current"的BTF指针。这个指针可以用来在帮助函数中接收一个task_struct类型的ARG_PTR_TO_BTF_ID。 返回值:返回指向当前task的指针。 162.long bpf_bprm_opts_set(struct linux_binpr…

iOS开发-hook之Method Swizzle更改原有方法实现流程

iOS开发-hook之Method Swizzle更改原有方法实现流程 一 Hook是什么&#xff1f; Hook 简介 Hook&#xff0c;中文译为“挂钩”或“钩子”。通过hook可以让别人的程序执行自己所写的代码。 一段程序的执行流程是 A -> B -> C&#xff0c;现在我们在 A 和 B 之间插入一…

一款基于过滤器的线程共享变量的清理机制

项目中常常用到线程共享变量。如多个函数或对象之间传递参数。循环读取缓存或数据库时时用共享变量减少读取次数。某类特殊对象的持有等。一般用finally去强制释放共享变量。但释放时机有时并不能准确的把握。为此&#xff0c;基于过滤器写了个个释放机制。 过滤器如下&#x…

ubuntu22.04 DNSSEC(加密DNS服务) configuration

/etx/systemd/resolved.conf是ubuntu下DNS解析服务配置文件&#xff0c;systemd为ubuntu下system and service配置目录 step 1——修改resolved.conf参数 管理员权限打开 /systemd/resolved.conf sudo nano /etc/systemd/resolved.conf修改如下&#xff1a; # This file i…

vr禁毒毒驾模拟体验从源头拒绝毒品,预防毒品

俗话说&#xff0c;一念天堂&#xff0c;一念地狱。吸毒一口&#xff0c;掉入虎口。吸毒对人体的危害非常大&#xff0c;普通人吸毒会导致家破人亡&#xff0c;明星吸毒会毁掉自己的大好星途。没有感同身受&#xff0c;何来悲喜相通&#xff0c;毒品危害认知VR模拟情景体验是VR…

利用频谱仪进行简单的2.4G 频率测试

一、概述 1. 信号源 我们开发2.4G 无线产品的时候&#xff0c;经常需要对产品的无线信号进行测试&#xff0c;以确定精确的频率。在进行频率测试之前&#xff0c;我们的2.4G 射频芯片需要进入单载波模式。 2. 频谱仪 这里选择的是普源的频谱仪。测试范围是 9kHz - 3.2GHz。…

Jtti:Linux内存管理中的slab缓存怎么实现

在Linux内存管理中&#xff0c;slab缓存是一种高效的内存分配机制&#xff0c;用于管理小型对象的内存分配。slab缓存的实现是通过SLAB分配器来完成的&#xff0c;它在Linux内核中对内存分配进行优化。 SLAB分配器将内存分为三个区域&#xff1a;slab、partial、和empty。 Slab…

hive 全量表、增量表、快照表、切片表和拉链表

全量表&#xff1a;记录每天的所有的最新状态的数据&#xff0c;增量表&#xff1a;记录每天的新增数据&#xff0c;增量数据是上次导出之后的新数据。快照表&#xff1a;按日分区&#xff0c;记录截止数据日期的全量数据切片表&#xff1a;切片表根据基础表&#xff0c;往往只…