关于前端:NodeJSExpress框架实现-Token-验证免密登录-一

15次阅读

共计 3637 个字符,预计需要花费 10 分钟才能阅读完成。

看文章之前,强烈建议先把我的项目拉取下来!案例来自小弟的开源我的项目「我的项目 Github」

文章内容只是集体学习的一些总结经验,不具备权威性,这是 Node 服务端的实现,前面会写前端的实现

什么是 Token 验证

常见的 Token 验证形式种:

  • OAuth2,例如:微信受权登录 (貌似也属于 Token 验证)
  • 基于 JWT 的 Token 验证,KiteBlog 外面应用的就是这种。

举荐浏览:

JWT 超详细分析

说一说几种罕用的登录认证形式,你用的哪种

什么是 JWT (JSON WEB TOKEN)?

举荐浏览:

JSON Web Token 入门教程

JSON Web Token – 在 Web 利用间平安地传递信息

NodeJS (Express) 中实现 Token 的生成和验证

装置 jsonwebtoken 和 express-jwt

首先咱们先装置 jsonwebtokenexpress-jwt 这两个中间件

jsonwebtoken: 用于生成 Token。它也有解析 Token 的性能

express-jwt: 用于解析 Token(比 jsonwebtoken 解决不便), 它把解析之后的数据,寄存到 requset.user

# 装置 jsonwebtoken
npm i jsonwebtoken

# 装置 express-jwt
npm i express-jwt

复制代码

生成 token

如果你看了下面 JWT 介绍的文章,就晓得 JWT 是由三局部组成的,别离是 载荷 (Payload) 头部 (Header) 签名(Signature)

jsonwebtoken 给咱们提供了 sign(payload, secretOrPrivateKey, [options, callback]) 办法。sign 办法对应的其实就是 JWT 签名 (Signature) 的动作

payload:荷载,参数类型:对象 secretOrPrivateKey:自定义的密钥,密钥属于敏感信息。参数类型:字符串 options:能够配置 header、荷载、指定算法类型。参数类型:对象 callback:回调

眼尖的敌人应该发现,payloadoptions 两个 参数 都能够配置荷,上面有例子。依据本人的习惯抉择就好

Payload 局部 JWT 规定了 7 个官网字段, 这些字段都是可选字段。可间接以对象的模式传给 payload 参数。

iss (issuer):签发人
exp (expiration time):过期工夫
sub (subject):主题
aud (audience):受众
nbf (Not Before):失效工夫
iat (Issued At):签发工夫
jti (JWT ID):编号
复制代码

options 中也能够承受以上七个字段,不过字段名称有所区别。

iss ---- issuer
exp ---- expiresIn
sub ---- subject
aud ---- audience
nbf ---- notBefore
iat ---- noTimestamp
jti ---- jwtid
复制代码

除此之后 options 提供了 algorithmheader,别离对应应用的加密算法和 JWT 的 Header 局部,其实 algorithm 应该也是属于 Header 局部的。

说了这么多,其实咱们个别罕用的只有 exp(expiresIn)algorithm 这两个字段,

例子一:

token 的无效工夫是配置在 option

// 先引入 jsonwebtoken
var jsonWebToken = require('jsonwebtoken');

// 密钥,当然理论的我的项目中密钥应该变态一些
const SECRET_KEY = 'kite1874'

const token = jsonWebToken.sign({
    // Payload 局部,官网提供七个字段这边省略,能够携带一些能够辨认用户的信息。例如 userId。// 千万不要是用敏感信息,例如明码,Payload 是能够解析进去的。userId:user.userId
    role:user.role
},SECRET_KEY,{
    expiresIn:"24h", //token 有效期
    // expiresIn: 60 * 60 * 24 * 7,  两种写法
    // algorithm:"HS256"  默认应用 "HS256" 算法
})

console.log(token)
复制代码

例子二:

咱们也能够在 payload 里配置无效工夫

const token = jsonWebToken.sign({
    //exp 的值是一个工夫戳,这里示意 1h 后 token 生效
    exp:Math.floor(Date.now() / 1000) + (60 * 60)
    userId:user.userId
    role:user.role
},SECRET_KEY)
复制代码

jsonwebtoken 除了生成 token 外,还提供了解析验证 token 的办法,jwt.verify(token, secretOrPublicKey, [options, callback])

这里就不演示了,感兴趣的敌人能够参考文档:「JsonWebToken」

验证 token

express-jwt 是针对 express框架开发的 JWT Token 验证中间件。我先来简略说以下它的用法。

次要有两种形式,一种是哪些申请须要验证就往哪里加验证;另外一种是先给全副申请加上验证,再给不须要验证的申请配置 白名单

形式一:

var express = require('express');
var jwt = require('express-jwt');
var app = express();

//SECRET_KEY 要与生成 Token 时保持一致 
const SECRET_KEY = 'kite1874' 

// secret 为密钥,algorithms 为算法。须要留神的是,如果你生成 Token 的时候没有手动设置 algorithm 
// 默认是应用 HS256 来加密的。「express-jwt 6.0」版本须要加 algorithms: ['HS256'] , 说起来都是泪!app.get("/test", 
jwt({secret: SECRET_KEY, algorithms: ['HS256']}),
function(req,res){//do something...})
复制代码

看完下面的例子,很显然不合乎咱们的逾期,一个失常的我的项目有个几十个 api 是分分钟的事。咱们不可能一个个给他加上测验

形式二:

// 注册中间件,相当于配置一个全局 token 验证,unless 就是下面说的白名单
// 把不须要 token 验证的申请填进 path 里即可, 反对数组、字符串、正则

app.use(jwt({ secret: SECRET_KEY, algorithms: ['HS256']})
.unless({path: ['/auth/adminLogin',/^\/public\/.*/]}));
// /auth/adminLogin api 和 public 下的文件都不须要 token 验证
复制代码

这种形式是不是不便很多,而且更好看,保护起来也更不便

Token 解析进去的用户信息,默认寄存在 req.user, 能够间接 req.user.userId来应用生成 Token 时填进去的用户 id

你也通过 requestPropertyresultProperty 来设置用户信息寄存的对象。

这里就不开展,具体文档参考:express-jwt

验证错误处理

能够应用 app.use() 来注册解决验证不通过的状况

app.use(function (err, req, res, next) {if (err.name === 'UnauthorizedError') {res.status(401).send("干嘛呢?你想硬闯?!")
  }
})
复制代码

留神(集体了解,不具备权威性)

到这里 Token 的生成、验证、测验不通过错误处理就实现了。Token 生成个别是在登录之后生成,并返回给前端,前端拿到 Token , 并在每次申请 api 的时候携带上 Token , Token 就相当于这个用户的身份,不要轻易泄露。

Token 一旦签发,不能被动让它生效,只能期待它有效期过能力生效。也就是说就算你批改了明码,之前的 Token 也还是无效的。你能够批改后端生成 Token 时应用的密钥,不让之前的 Token 测验通过,然而这就示意之前所有生成 Token 都生效了,做不到针对某个用户进行登记。这显然也不适合的。所以用户批改明码时,前端个别都要革除之前保留的 Token, 再重获取新的 Token

有敌人应该会想到在后端把 Token 储存起来,每一个用户对应一个 token。批改账号时,再生成一个新的 Token 笼罩之前的 Token,但这就违反了应用 Token 的目标,Token 的应用很大水平就为了缩小服务器的压力。把尽可能多的信息存储在客户端而不是服务端。

应用 Token 能够进攻 CSRF 攻打,之前写过一篇对于网络安全的文章,感兴趣的敌人能够看一下「XSS 攻打、CSRF 攻打、SQL 注入、流量劫持(DNS 劫持、HTTP 劫持)—— 浏览器平安」

正文完
 0