JWT(jsonwebtoken)鉴权
密码正确的话,登录成功,根据用户信息生成唯一的token返回给客户端
安装jsonwebtoken用于生成token
npm i jsonwebtoken
导入jsonwebtoken
// 导入生成Token的包
const jwt = require('jsonwebtoken')
全局配置文件(里面有token的密钥)
config.js放在根目录
// 全局配置文件 config.js
module.exports = {
// 加密和解密 token 的密钥
jwtSecretKey: 'houpu No1. ^_^',
// token 有效期
expiresIn: '10m'
}
// 导入全局配置文件(里面有token的密钥)
const config = require('../../config')
使用jwt.sign对用户的信息进行加密,生成 token 字符串
jwt.sign 有三个参数依次是 生成token的数据,加密的形式,token有效期
加密前先处理用户信息,将用户的敏感信息置空
// 在服务器端生成 Token 字符串
const user = {
...result[0], // 解构用户信息
password: '', //密码等敏感信息置空
}
// 对用户的信息进行加密,生成 token 字符串
const tokenStr = jwt.sign(user, config.jwtSecretKey, {
expiresIn: config.expiresIn //tonken 有效期
})
// 对用户传过来的token进行解密,解析出用户的数据
const decoded = jwt.verify(tokenStr, config.jwtScretKey)
登录成功后将生成的token返回给客户端
// 调用 res.send 将Token响应给客户端
res.send({
status: 0,
data: {
user: user,
token: 'Bearer ' + tokenStr,
},
message: '登录成功!!!',
})
users路由模块和登录注册函数.js的完整代码
var express = require('express');
var router = express.Router();
// 导入数据库操作模块
const db = require('../../db/index')
// 导入生成Token的包
const jwt = require('jsonwebtoken')
// 导入全局配置文件(里面有token的密钥)
const config = require('../../config')
/**
* POST 用户登录
* @param username 用户名
* @param password 用户密码
*/
router.post('/login', (req, res, next) => {
// 通过 req.body 获取请求体中包含的 url-encoded 格式的数据
// console.log(req.body)
const userInfo = req.body
//对客户端的数据进行校验
if (userInfo.username == '' || userInfo.password == '') {
return res.send({
code: 1,
msg: '用户名和密码不能为空'
})
}
// 接收表单的数据
const userInfo = req.body
// 定义 SQL 语句
const sql = 'select * from ev_users where username=?'
// 执行 SQL 语句,根据用户名查询用户的信息
db.query(sql, userInfo.username, (err, result) => {
// 执行 SQL 语句失败
if (err) return res.send({
code: 5001,
msg: err
})
if (!result.length) return res.send({
code: 5002,
msg: '用户名或密码错误'
})
// 经过上方俩条判断条件,则证明执行 SQL 成功
// 在服务器端生成 Token 字符串
const user = {
...result[0], // 解构用户信息
password: '', //密码等敏感信息置空
}
// 对用户的信息进行加密,生成 token 字符串
const tokenStr = jwt.sign(user, config.jwtSecretKey, {
expiresIn: config.expiresIn //tonken 有效期
})
// 调用 res.send 将Token响应给客户端
res.send({
code: 0,
data: {
user: user,
token: 'Bearer ' + tokenStr,
},
message: '登录成功!!!',
})
});
module.exports = router;
解析token中间件
在刚刚我们完成了token的生成,现在我们做一个中间件用来解析token,来对用户进行身份认证
安装解析中间件
npm i express-jwt 或 pnpm i express-jwt 或 yarn add express-jwt
在App.js 中引入
//token解析中间件 一定要在路由之前配置解析 Token 的中间件
const { expressjwt } = require('express-jwt')
//引入解密
const config = require('./config')
注册全局中间件并解析token
// 注册全局中间件 链式调用 unless 方法,接收一个配置对象,path 字段设置一个正则表达式,
表示不需要 token 身份认证的路由前缀。
app.use(expressjwt({
// 加密时设置的密钥
secret: config.jwtSecretKey,
// 设置算法
algorithms: ['HS256'],
}).unless({
path: [
'/users/add',
'/users/login',
{
url: /^\/public\/.*/,
methods: ['GET', 'POST']
}
]
// path: ['/users/login','/users']
}))
注册全局错误中间件 当token失效时 返回信息
// 错误中间件 当token失效时 返回信息
app.use((err, req, res, next) => {
if(err.name === 'UnauthorizedError') {
return res.send({ code: err.status, msg: err.inner.message })
}
next()
})