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的更多相关文章

  1. Node.js基于Express框架搭建一个简单的注册登录Web功能

    这个小应用使用到了node.js  bootstrap  express  以及数据库的操作 :使用mongoose对象模型来操作 mongodb 如果没了解过的可以先去基本了解一下相关概念~ 首先注 ...

  2. node.js,express入门看详细篇

    先最简单的代码 安装 npm install express app.js 代码内容 const express = require('express') const app = express() ...

  3. node.js之express框架

    之前学习过node.js接触过express框架,最近为了编写一个mock server正好用到了express.下面正好就跟大家介绍一下关于express.今天的内容主要围绕这么几个方面? expr ...

  4. 【node.js】Express 框架

    Express 是一个简洁而灵活的 node.js Web应用框架, 提供了一系列强大特性帮助你创建各种 Web 应用,和丰富的 HTTP 工具. 使用 Express 可以快速地搭建一个完整功能的网 ...

  5. 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 ...

  6. Node.js、express、mongodb 实现分页查询、条件搜索

    前言 在上一篇Node.js.express.mongodb 入门(基于easyui datagrid增删改查) 的基础上实现了分页查询.带条件搜索. 实现效果 1.列表第一页. 2.列表第二页 3. ...

  7. Node.js、express、mongodb 入门(基于easyui datagrid增删改查)

    前言 从在本机(win8.1)环境安装相关环境到做完这个demo大概不到两周时间,刚开始只是在本机安装环境并没有敲个Demo,从周末开始断断续续的想写一个,按照惯性思维就写一个增删改查吧,一方面是体验 ...

  8. node.js和express.js安装和使用步骤 [windows]

    PS: NODEJS:https://nodejs.org NPM:https://www.npmjs.com/ 一.node.js安装与配置 到https://nodejs.org/en/downl ...

  9. node.js框架express的安装

    node.js框架express的安装 首先假定你已经安装了 Node.js,接下来为你的应用创建一个目录,然后进入此目录并将其作为当前工作目录. $ mkdir myapp $ cd myapp 通 ...

  10. Node.js系列-express(上)

    前言 Node.js系列的第一篇:http,大概描述了通过使用node.js内置的api创建一个服务并监听request实现简单的增删改查.现在,我们就通过通读express官网及使用express框 ...

随机推荐

  1. Flask基础(05)-->路由的基本定义

    # 导入Flask from flask import Flask # 创建Flask的应用程序 app = Flask(__name__) # http://127.0.0.1:5000/123或者 ...

  2. EL十一大内置对象

    这是一个内置对象可以直接拿来使用,不需要再去声明. 1.读取页面上下文: (1)pageContext对象: 获取URL和URI: <body> URI:${pageContext.req ...

  3. .net core 3.0 Signalr - 01 基础篇

    因为将signalr作为单独的站点,此处需要建立两个项目,一个专门用于signalr作为推送项目,一个客户端(实际的业务项目) ## 基础知识速览 ### Clients对象属性 | 属性 | 描述 ...

  4. SpringBootSecurity学习(17)前后端分离版之 OAuth2.0 数据库(JDBC)存储客户端

    自动批准授权码 前面我们授权的流程中,第一步获取授权码的时候,都会经历一个授权是否同意页面: 这个流程就像第三方登录成功后,提问是否允许获取昵称和头像信息的页面一样,这个过程其实是可以自动同意的,需要 ...

  5. 集合线性表--List之ArrayList

    集合操作——线性表 List: add().remove().subList().list.toArray().array.asList(). List排序:  Collections.sort(li ...

  6. 快学Scala 第十三课 (类型层级,对象相等性)

    Scala 类型层级: 对象相等性: 和Java一样要重写equals方法和hashcode方法 class Student(val id: Int, val name: String) { over ...

  7. 基于.NET环境,C#语言 实现 TCP NAT

    基于.NET平台和C#语言实现TCP NAT穿越        1.<C# WinForm 跨线程访问控件(实用简洁写法)>       2.<基于.NET环境,C#语言 实现 TC ...

  8. hibernate 搭建框架

    需要用的包 Hibernate的日志记录: * Hibernate日志记录使用了一个slf4j: * SLF4J,即简单日志门面(Simple Logging Facade for Java),不是具 ...

  9. 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- ...

  10. JAVA阻塞(IO)和非阻塞(NIO)

    查看这篇文章,了解更多关于Java的阻塞和非阻塞替代创建套接字的信息. 套接字使用TCP / IP传输协议,是两台主机之间的最后一块网络通信. 您通常不必处理它们,因为它们之上构建了协议,如HTTP或 ...