Node.js 使用 express-jwt 解析 JWT
Node.js 上 Token 鉴权常用的是 passport,它可以自定义校验策略,但如果你是用 express 框架,又只是解析 JWT 这种简单需求,可以尝试下 express-jwt 这个中间件。

关于 JWT
JWT 全称 JSON Web Token,是代替传统 session 认证的解决方案。其原理是服务端生成一个包含用户唯一标识的 JSON 对象,颁发给客户端。客户端请求需要权限的接口时,只要把这个 JSON 再原样发回给服务端,服务器通过解析就可识别用户。
它通常是这个样子:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
这个 JSON 对象通过 . 分成三段,包含了请求头(加密算法)、负载信息(如 userId、过期时间),还有通过服务端密钥生成的签名来保证不被篡改。
这种机制使服务端不再需要存储 Token,因此是非常轻量的用户认证方案。并且对于微服务这种需要不同服务间共用 Token 的跨域认证,JWT 是目前的首选。
关于 express-jwt
express-jwt 是 Node.js 的一个开源库,由 ID 认证服务提供商 auth0 开发,是专用于 express 框架下解析 JWT 的中间件。
它使用非常简单,而且会自动把 JWT 的 payload 部分赋值于 req.user,方便逻辑部分调用。
开始使用
安装
npm install express-jwt
加入中间件
const expressJwt = require('express-jwt')
app.use(expressJwt({
secret: 'secret12345' // 签名的密钥 或 PublicKey
}).unless({
path: ['/login', '/signup'] // 指定路径不经过 Token 解析
}))
生成 Token
生成 Token 的方式依然使用 jsonwebtoken,比如将下列代码加入到登录接口的返回部分:
const jwt = require('jsonwebtoken')
app.post('/login', function (req, res) {
// 注意默认情况 Token 必须以 Bearer+空格 开头
const token = 'Bearer ' + jwt.sign(
{
_id: user._id,
admin: user.role === 'admin'
},
'secret12345',
{
expiresIn: 3600 * 24 * 3
}
)
res.json({
status: 'ok',
data: { token: token }
})
})
获取解析内容
当收到带 Token 的请求,如果解析成功,就可以在路由回调里通过 req.user 来访问:
app.get('/protected', function (req, res) {
if (!req.user.admin)
return res.sendStatus(401)
res.sendStatus(200)
})
req.user 实际就是 JWT 的 payload 部分:
{
_id: '5dbbc7daaf7dfe003680ba39',
admin: true,
iat: 1572587484,
exp: 1573192284
}
解析失败
如果解析失败,会抛出 UnauthorizedError,可以通过后置中间件来捕获:
app.use(function (err, req, res, next) {
if (err.name === 'UnauthorizedError') {
res.status(401).send('invalid token')
}
})
修改结果字段
默认解析结果会赋值在 req.user,也可以通过 requestProperty 来修改:
app.use(expressJwt({
secret: 'secret12345',
requestProperty: 'auth'
}))
允许无 Token 请求
当接口允许不带 Token 和带 Token 两种状态的访问时(比如文章详情登录后判断点赞),可以通过 credentialsRequired: false 来对无 Token 请求不进行解析和抛出异常。
app.use(expressJwt({
secret: 'secret12345',
credentialsRequired: false
}))
自定义解析
默认情况下,express-jwt 是从请求 Headers 的 Authorization 字段来获取 Token 并解析。
通过 getToken 也可以自定义一些解析逻辑,比如使用其他 Header 字段,自定义抛出异常等:
app.use(expressJwt({
secret: 'secret12345',
credentialsRequired: false,
getToken: function fromHeaderOrQuerystring (req) {
if (req.headers.authorization && req.headers.authorization.split(' ')[0] === 'Bearer') {
return req.headers.authorization.split(' ')[1]
} else if (req.query && req.query.token) {
return req.query.token
}
return null
}
}))
作废 Token
在 JWT 机制中,由于 Token 通常不进行存储,如果想作废某一条 Token,一般都是通过被动的方式。
常用的方式是建立某个字段的黑名单(比如 TokenId),对所有 Token 进行过滤,express-jwt 专门提供了回调来处理这种情况:
const expressJwt = require('express-jwt')
const blacklist = require('./blacklist')
let isRevokedCallback = function(req, payload, done){
let issuer = payload.iss
let tokenId = payload.jti
blacklist.getRevokedToken(issuer, tokenId, function(err, token){
if (err) { return done(err) }
return done(null, !!token) // 第二个参数为 true 则不通过
})
}
app.use(expressJwt({
secret: 'secret12345',
isRevoked: isRevokedCallback
}))
更多用法可以查看 官方文档
本文属于原创,首发于微信公众号「面向人生编程」,如需转载请后台留言。

关注后回复以下信息获取更多资源
回复【资料】获取 Python / Java 等学习资源
回复【插件】获取爬虫常用的 Chrome 插件
回复【知乎】获取最新知乎模拟登录
Node.js 使用 express-jwt 解析 JWT的更多相关文章
- Node.js基于Express框架搭建一个简单的注册登录Web功能
这个小应用使用到了node.js bootstrap express 以及数据库的操作 :使用mongoose对象模型来操作 mongodb 如果没了解过的可以先去基本了解一下相关概念~ 首先注 ...
- node.js,express入门看详细篇
先最简单的代码 安装 npm install express app.js 代码内容 const express = require('express') const app = express() ...
- node.js之express框架
之前学习过node.js接触过express框架,最近为了编写一个mock server正好用到了express.下面正好就跟大家介绍一下关于express.今天的内容主要围绕这么几个方面? expr ...
- 【node.js】Express 框架
Express 是一个简洁而灵活的 node.js Web应用框架, 提供了一系列强大特性帮助你创建各种 Web 应用,和丰富的 HTTP 工具. 使用 Express 可以快速地搭建一个完整功能的网 ...
- Code Your First API With Node.js and Express: Set Up the Server
How to Set Up an Express API Server in Node.js In the previous tutorial, we learned what the REST ar ...
- Node.js、express、mongodb 实现分页查询、条件搜索
前言 在上一篇Node.js.express.mongodb 入门(基于easyui datagrid增删改查) 的基础上实现了分页查询.带条件搜索. 实现效果 1.列表第一页. 2.列表第二页 3. ...
- Node.js、express、mongodb 入门(基于easyui datagrid增删改查)
前言 从在本机(win8.1)环境安装相关环境到做完这个demo大概不到两周时间,刚开始只是在本机安装环境并没有敲个Demo,从周末开始断断续续的想写一个,按照惯性思维就写一个增删改查吧,一方面是体验 ...
- node.js和express.js安装和使用步骤 [windows]
PS: NODEJS:https://nodejs.org NPM:https://www.npmjs.com/ 一.node.js安装与配置 到https://nodejs.org/en/downl ...
- node.js框架express的安装
node.js框架express的安装 首先假定你已经安装了 Node.js,接下来为你的应用创建一个目录,然后进入此目录并将其作为当前工作目录. $ mkdir myapp $ cd myapp 通 ...
- Node.js系列-express(上)
前言 Node.js系列的第一篇:http,大概描述了通过使用node.js内置的api创建一个服务并监听request实现简单的增删改查.现在,我们就通过通读express官网及使用express框 ...
随机推荐
- Flask基础(05)-->路由的基本定义
# 导入Flask from flask import Flask # 创建Flask的应用程序 app = Flask(__name__) # http://127.0.0.1:5000/123或者 ...
- EL十一大内置对象
这是一个内置对象可以直接拿来使用,不需要再去声明. 1.读取页面上下文: (1)pageContext对象: 获取URL和URI: <body> URI:${pageContext.req ...
- .net core 3.0 Signalr - 01 基础篇
因为将signalr作为单独的站点,此处需要建立两个项目,一个专门用于signalr作为推送项目,一个客户端(实际的业务项目) ## 基础知识速览 ### Clients对象属性 | 属性 | 描述 ...
- SpringBootSecurity学习(17)前后端分离版之 OAuth2.0 数据库(JDBC)存储客户端
自动批准授权码 前面我们授权的流程中,第一步获取授权码的时候,都会经历一个授权是否同意页面: 这个流程就像第三方登录成功后,提问是否允许获取昵称和头像信息的页面一样,这个过程其实是可以自动同意的,需要 ...
- 集合线性表--List之ArrayList
集合操作——线性表 List: add().remove().subList().list.toArray().array.asList(). List排序: Collections.sort(li ...
- 快学Scala 第十三课 (类型层级,对象相等性)
Scala 类型层级: 对象相等性: 和Java一样要重写equals方法和hashcode方法 class Student(val id: Int, val name: String) { over ...
- 基于.NET环境,C#语言 实现 TCP NAT
基于.NET平台和C#语言实现TCP NAT穿越 1.<C# WinForm 跨线程访问控件(实用简洁写法)> 2.<基于.NET环境,C#语言 实现 TC ...
- hibernate 搭建框架
需要用的包 Hibernate的日志记录: * Hibernate日志记录使用了一个slf4j: * SLF4J,即简单日志门面(Simple Logging Facade for Java),不是具 ...
- Ubuntu 16.04安装snort含问题解决
源码方式安装 wget https://www.snort.org/downloads/snort/daq-2.0.6.tar.gz tar xvzf daq-2.0.6.tar.gz cd daq- ...
- JAVA阻塞(IO)和非阻塞(NIO)
查看这篇文章,了解更多关于Java的阻塞和非阻塞替代创建套接字的信息. 套接字使用TCP / IP传输协议,是两台主机之间的最后一块网络通信. 您通常不必处理它们,因为它们之上构建了协议,如HTTP或 ...