Loading [MathJax]/jax/input/TeX/config.js
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >JWT 到底应该怎么用才对?

JWT 到底应该怎么用才对?

原创
作者头像
松鼠专栏
修改于 2020-04-02 03:02:02
修改于 2020-04-02 03:02:02
3.4K0
举报
文章被收录于专栏:松鼠专栏松鼠专栏

一、概述

JWT 全称为 JSON Web Token,是一份开源的标准协议,它定义了一种传输内容基于 JSON、轻量级、安全的数据传输方式。

二、细节

每个 JWT 都由 Header、Payload、Signature 3 部分组成,同时用点进行拼接,形式如下:

代码语言:txt
AI代码解释
复制
Header.Payload.Signature

Header

Header 部分是一个经过 Base64 编码后的 JSON 对象。对象的内容通常包括 2 个字段,形式如下:

代码语言:txt
AI代码解释
复制
{
  "typ": "JWT",
  "alg": "HS256"
}

其中,typ(全称为 type)指明当前的 Token 类型为 JWT,alg(全称为 algorithm)指明当前的签名算法是 HS256

Payload

Payload 部分也是一个经过 Base64 编码后的 JSON 对象,对象的属性可以划分成 3 部分:保留字段、公共字段、私有字段。

保留字段是 JWT 内部声明,具有特殊作用的字段,包括

  • iss(全称为 issuer),指明 JWT 是由谁签发的
  • sub(全称为 subject),指明 JWT 的主题(也可理解为面向用户的类型)
  • aud(全称为 audience),指明 JWT 希望谁签收
  • exp(全称为 expiration time),指明 JWT 的过期时间,过期时间需大于签发时间
  • nbf(全称为 not before time),指明 JWT 在哪个时间点生效
  • iat(全称为 issued at time),指明 JWT 的签发时间
  • jti(全称为 JWT ID),指明 JWT 唯一 ID,用于避免重放攻击

公共字段和私有字段都是用户可以任意添加的字段,区别在于公共字段是一些约定俗成,被普遍使用的字段,而私有字段更符合实际的应用场景。

当前已有的公共字段可以从 JSON Web Token Claims 中找到。

Payload 的结构形式如下:

代码语言:txt
AI代码解释
复制
{
  "sub": "1234567890",
  "name": "John Doe",
  "iat": 1516239022
}

Signature

Signature 部分是 JWT 根据已有的字段生成的,它的计算方式是使用 Header 中定义的算法,使用用户定义的密钥,对经过 Base64 编码后的 Header 和 Payload 组成的字符串进行加密,形式如下:

代码语言:txt
AI代码解释
复制
HMACSHA256(base64(header) + '.' + base64(payload))

三、应用场景

业界普遍认可的应用场景主要有以下几种:

防止传输数据篡改

数据数据篡改指的是数据在传输过程中被截获,修改的行为。

JWT 本身可以使用加密算法对传输内容进行签名,即使数据被截获,也很难同时篡改签名和传输内容。

鉴权

鉴权指的是验证用户是否有访问系统的权利。

部分人使用 JWT 来取代传统的 Session + Cookie,理由是:

  • 服务器开销小。使用 Session + Cookie 需要服务器缓存用户数据,而使用 JWT 则是直接将用户数据下发给客户端,每次请求附带一并发送给服务器。
  • 扩展性好。服务器不缓存用户数据的好处是可以很方便的进行横向扩容
  • 适用于单点登录。JWT 很适合做跨域情况下的单点登录
  • 适用于搭配 RESTFul API 使用。基于 RESTFul 架构设计的 API 需遵循 RESTFul 的无状态原则,而基于 JWT 的鉴权恰恰是把状态转移到了客户端

基于 JWT 的鉴权一般处理逻辑是:

基于 JWT 的鉴权方案也存在一些争议:

  • 服务器签发 JWT 后,并不能主动注销,若存在恶意请求则很难制止。其实可以通过 Token 黑名单的方式去解决。
  • JWT 减少了服务器的开销,却增加了带宽的开销,JWT 生成的 Token 在体积上比 SessionID 大很多,意味着每次请求相比之前要携带更多的数据量。这个确实是这样,所以应该尽量只在 JWT 内放必要的数据。
  • JWT 在鉴权方面并非完全优于 Session-Cookie,举个例子,SessionID 也可以通过签名的方式来防止篡改。

四、使用

以下使用 Node.js 和 JavaScript 演示 JWT 在鉴权方面的应用,涉及的库有:

如何生成 Token

Token 的生成一般是客户端发送登录请求,服务器使用密钥生成 Token 并放入响应体中,以下为服务端的 Token 生成逻辑。

代码语言:txt
AI代码解释
复制
// 文件位置:controller/v1/token.js
const config = require('config') // 加载服务器配置
const jwt = require('jsonwebtoken') // 加载 jwt Node.js 语言实现

/**
 * 创建 Token 控制器
 * @param {Object} ctx 请求上下文
 */
async function create(ctx) {
  const username = ctx.request.body.username
  const password = ctx.request.body.password
  
  if (!username || !password) {
    ctx.throw(400, '参数错误')
    return
  }

  // 省略:用户名密码数据库校验
  const user = { id: '5e54c02a2b073de564fe8034' } // 用户信息
  const secret = config.get('secret') // 获取保存于配置中的密钥
  const opt = { expiresIn: '2d' } // 设置 Token 过期时间为 2 天

  ctx.body = jwt.sign(user, secret, opt) // 生成并返回 token
}

module.exports = {
  create,
}

客户端携带 Token 进行请求

客户端一般情况下将 Token 放在 Http Header 的 Authorization 中,随请求发送给服务器。

代码语言:txt
AI代码解释
复制
// 文件位置:views/index.pug
var request = axios.create({ baseURL: '/api/v1' }) // 创建请求实例
var token // 为了方便这里使用全局变量,正常情况下应该放入其他存储介质中,如,localStorage,此处省略获取逻辑

// 监听正常请求按钮单击事件,发起请求
document.querySelector('#normal').addEventListener('click', function() {
  if (!token) {
    alert('请登录')
    return
  }

  request.get('/users', {
    headers: {
      Authorization: 'Bearer ' + token, // 绑定 token 到 header 中
    },
  }).then(function({ data }) {
    document.querySelector('#response').innerHTML = JSON.stringify(data)
  }).catch(function(err) {
    console.log('Request Error: ', err)
  })
})

服务器如何验证 Token

验证操作一般放在服务器的中间件

代码语言:txt
AI代码解释
复制
const config = require('config') // 加载服务器配置
const jwt = require('jsonwebtoken') // 加载 jwt Node.js 语言实现

// 定义中间件函数
module.exports = async (ctx, next) => {
  const path = ctx.url // 获取请求 URL
  const method = ctx.method.toLowerCase() // 获取请求方法
  
  // 请求白名单,白名单中的请求不经过中间件 token 校验
  const whiteList = [
    { path: /^\/api\/v[1-9]\/tokens/, method: 'post' },
    { path: /^\/api/, reverse: true }, // 非 /api 开头的资源都不需要经过请求校验
  ]
  
  // 请求白名单检查函数  
  const checker = (i) => {
    const matchPath = i.path.test(path)
    const matchMethod = i.method ? i.method === method : true

    return (i.reverse ? !matchPath : matchPath) && matchMethod
  }

  // 白名单逻辑判断
  if (whiteList.some(checker)) {
    await next()
    return
  }

  // 获取 http header 中的 token
  const token = (ctx.header.authorization || '').replace('Bearer ', '')

  // token 有效性校验
  try {
    const data = jwt.verify(token, config.secret)
    ctx.userInfo = data
  } catch (e) {
    ctx.throw(400, 'Token 错误')
  }
  
  await next()
}

查看完整代码请前往 GitHub 搜索用户 yo-squirrel

觉得写得不错可以关注下微信公众号「松鼠专栏

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
Java实现JWT的Token认证机制[通俗易懂]
JWT是基于token的身份认证的方案。 json web token全称。可以保证安全传输的前提下传送一些基本的信息,以减轻对外部存储的依赖,减少了分布式组件的依赖,减少了硬件的资源。 可实现无状态、分布式的Web应用授权,jwt的安全特性保证了token的不可伪造和不可篡改。 本质上是一个独立的身份验证令牌,可以包含用户标识、用户角色和权限等信息,以及您可以存储任何其他信息(自包含)。任何人都可以轻松读取和解析,并使用密钥来验证真实性。
全栈程序员站长
2022/08/04
5.6K0
虾皮二面:什么是 JWT? 如何基于 JWT 进行身份验证?
JWT (JSON Web Token) 是目前最流行的跨域认证解决方案,是一种基于 Token 的认证授权机制。从 JWT 的全称可以看出,JWT 本身也是 Token,一种规范化之后的 JSON 结构的 Token。
Guide哥
2022/11/07
1.3K0
虾皮二面:什么是 JWT? 如何基于 JWT 进行身份验证?
【Node】使用 koa 实现一个简单JWT鉴权
全称 JSON Web Token, 是目前最流行的跨域认证解决方案。基本的实现是服务端认证后,生成一个 JSON 对象,发回给用户。用户与服务端通信的时候,都要发回这个 JSON 对象。
GopalFeng
2022/08/01
1.9K0
【Node】使用 koa 实现一个简单JWT鉴权
手把手搭建koa2后端服务器-登录认证
现在我们的开发方式都是采用前后端分离的方式,因此后端一般都只提供数据,这就造成前后端域名不同,存在跨域请求的问题,浏览器为了安全方面考虑,对跨域请求有限制。为了避免非同源请求的失败,我们需要采取跨域资源共享 CORS 来解决这个问题。
星星在线
2022/04/27
7640
手把手搭建koa2后端服务器-登录认证
什么是JWT?
JSON Web Token (JWT) 是一个开源标准(RFC 7519),它定义了一种紧凑且自完备的方法用于在各参与方之间以JSON对象传递信息。以该种方式传递的信息已经被数字签名,因而可以被验证并且被信任。JWT既可以使用盐(secret)(HMAC算法)进行签名,也可以使用基于RSA/ECDSA算法的公钥/秘钥对进行签名。
Steve Wang
2022/04/13
1K0
什么是JWT?
【秒杀】JWT-满足你水管服务器的状态信息携带方式
JWT,即为JSON Web Token,拆开来看,JSON是JavaScript的一种对象数据存储方式,Token则是令牌,组合在一起就是在Web应用上,使用令牌的JSON数据,乍一看还是有点抽象,
Ar-Sr-Na
2024/03/31
2940
【秒杀】JWT-满足你水管服务器的状态信息携带方式
一篇文章告诉你JWT的实现原理
编辑:业余草 来源:https://www.xttblog.com/?p=4940 写篇文章不容易,昨天晚上深夜写完忘记保存了。联想一下那个画面,真的是泪目啊! 哎,过去的就让他过去吧,今天我们继续
业余草
2020/04/08
2.3K0
一篇文章告诉你JWT的实现原理
JWT鉴权详解与实战
JSON Web Token (JWT) 是一个开放标准 ( RFC 7519 ),它定义了一种紧凑且自包含的方式,用于在各方之间以 JSON 对象的形式安全传输信息。此信息可以验证和信任,因为它是数字签名的。JWT 可以使用密钥(使用HMAC算法)或使用RSA或ECDSA的公钥/私钥对进行签名。
素履coder
2022/09/23
2K0
JWT鉴权详解与实战
JWT(JSON Web Token)
HTTP Basic Auth 一种最古老的安全认证方式,这种方式就是简单的访问API的时候,带上访问的username和password,由于信息会暴露出去,所以现在也越来越少用了。
Se7en258
2021/05/18
1.1K0
JWT(JSON Web Token)
不懂就学,什么是JWT?
需要了解一门技术,首先从为什么产生开始说起是最好的。JWT主要用于用户登录鉴权,所以我们从最传统的session认证开始说起。
java技术爱好者
2021/12/07
4980
不懂就学,什么是JWT?
JWT 鉴权
使用 koa-jwt + jsonwebtoken 完成用户鉴权功能。 项目地址:https://github.com/Ewall1106/mall 安装 首先我们安装 koa-jwt 和 jsonwebtoken这两个 npm 包。 $ npm install koa-jwt jsonwebtoken --save 先明确一下两者的关系:koa-jwt 是负责对 token 进行验证的,而 jsonwebtoken 是负责生成 token 的。 JWT 鉴权 在 app.js 中引入并使用。 co
Ewall
2020/11/12
1.8K0
JWT详解「建议收藏」
这种基于token的认证方式相比传统的session认证方式更节约服务器资源,并且对移动端和分布式更加友好。其优点如下:
全栈程序员站长
2022/08/25
1.7K0
JWT详解「建议收藏」
你们leader 可能都不知道的用户鉴权机制的原理
互联网年代,一个网站的用户数,就是这个网站的命脉,那么,这些用户的账户安全问题很成问题,于是行业大佬们,开始忧国忧民,研究出很多解决当下痛点的解决方案。从最开始的前后端不分离,研究出来的session-cookie,到后来基于前端存储的Token 验证 ,后来网站越来越多多了,为了不总是注册账号推出来的OAuth权限,以及一个公司项目太多了,为了防止重复登录开启的单点登录。
用户7413032
2022/03/09
1.4K0
你们leader 可能都不知道的用户鉴权机制的原理
Koa2+MongoDB+JWT实战--Restful API最佳实践
Web API 已经在最近几年变成重要的话题,一个干净的 API 设计对于后端系统是非常重要的。
前端森林
2020/04/23
10.2K0
Koa2+MongoDB+JWT实战--Restful API最佳实践
辩证的眼光搞懂 JWT 这个知识点
JWT 由三部分组成:Header,Payload,Signature 三个部分组成,并且最后由.拼接而成。
coder_koala
2020/03/03
1.4K0
辩证的眼光搞懂 JWT 这个知识点
Node.js 使用 express-jwt 解析 JWT
JWT 全称 JSON Web Token,是代替传统 session 认证的解决方案。其原理是服务端生成一个包含用户唯一标识的 JSON 对象,颁发给客户端。客户端请求需要权限的接口时,只要把这个 JSON 再原样发回给服务端,服务器通过解析就可识别用户。
张凯强
2019/11/19
3.8K0
Node.js 使用 express-jwt 解析 JWT
入门 | egg.js 入门之egg-jwt
这里创建并安装完成以后,需要再次初始化俩包,分别为egg-cors与egg-jwt token 生成的验证包
mySoul
2020/08/03
1.6K0
使用python实现后台系统的JWT认证
專 欄 ❈ 茶客furu声,Python中文社区专栏作者 博客: http://www.jianshu.com/p/537b356d34c9 ❈ 今天的文章介绍一种适用于restful+json的API认证方法,这个方法是基于jwt,并且加入了一些从oauth2.0借鉴的改良。 1. 常见的几种实现认证的方法 首先要明白,认证和鉴权是不同的。认证是判定用户的合法性,鉴权是判定用户的权限级别是否可执行后续操作。这里所讲的仅含认证。认证有几种方法: 1.1 basic auth
Python中文社区
2018/01/31
3.2K0
使用NodeJS实现JWT原理
JWT是json web token的简称,本文介绍它的原理,最后后端用nodejs自己实现如何为客户端生成令牌token和校验token 一 为什么需要会话管理 我们用 nodejs 为前端或者其他服务提供 resful 接口时,http 协议他是一个无状态的协议,有时候我们需要根据这个请求的上下获取具体的用户是否有权限,针对用户的上下文进行操作。所以出现了cookies session还有jwt这几种技术的出现, 都是对HTTP协议的一个补充。使得我们可以用HTTP协议+状态管理构建一个的面向用户的WE
用户1097444
2022/06/29
1.1K0
使用NodeJS实现JWT原理
Django+JWT实现Token认证
基于Token的鉴权机制越来越多的用在了项目中,尤其是对于纯后端只对外提供API没有web页面的项目,例如我们通常所讲的前后端分离架构中的纯后端服务,只提供API给前端,前端通过API提供的数据对页面进行渲染展示或增加修改等,我们知道HTTP是一种无状态的协议,也就是说后端服务并不知道是谁发来的请求,那么如何校验请求的合法性呢?这就需要通过一些方式对请求进行鉴权了
小尘哥
2019/03/01
2.9K1
相关推荐
Java实现JWT的Token认证机制[通俗易懂]
更多 >
LV.0
这个人很懒,什么都没有留下~
作者相关精选
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档