在Node.js(express 框架)中使用 JWT 进行身份认证

发布于:2024-05-07 ⋅ 阅读:(30) ⋅ 点赞:(0)

一、JWT 认证机制

JWT 认证机制(图片来源于网络,侵权删除):

JWT 认证机制

关于 JWT 原理可参考:https://ruanyifeng.com/blog/2018/07/json_web_token-tutorial.html

二、安装 JWT 相关的包

yarn add jsonwebtoken express-jwt

  • jsonwebtoken 用于生成 JWT 字符串
  • express-jwt 用于将 JWT 字符串解析还原成 JSON 对象

三、基本使用

用户登录前:用户输入用户名密码进行登录 --> 用户名密码正确 --> 生成 JWT 字符串并携带用户信息发送至客户端

用户登录前

用户登录成功后 --> 客户端每次发送请求经过中间件将 JWT 解析还原成 JSON 字符串 --> JWT 解析成功 --> 处理相关逻辑

 用户登录后

1、生成 JWT 字符串

routes/users.js 文件中实现用户登录功能

var express = require('express');
var router = express.Router();
// 此处省略 mongodb 数据库连接相关操作
const mongoDB = require('../db/conMongoDB');

// 用于生成 JWT 字符串的包
const jwt = require('jsonwebtoken');
// 定义 secret 密钥(自定义)
const secretKey = 'abcd';
// token 过期时间(自定义)
const expiresIn = '86400s';

登录功能实现:

router.post('/login', async function (req, res, next) {
    const usersTable = mongoDB.collection('users');
    // 判断用户名密码是否存在
    const findResult = await usersTable.findOne(req.body);
    if (findResult) {
        res.send({ success: true, code: 0, msg: "登录成功", username: findResult.username, 
            // 生成 JWT 字符串,三个参数:用户信息对象、加密密钥、配置对象
            token: jwt.sign({ email: req.body.email }, secretKey, { expiresIn: expiresIn })
        });
    } else {
        res.send({ success: false, code: 1, msg: "登录失败", data: "" });
    }
})
2、添加中间件,解析 JWT 字符串

该项目是使用 express-generator 生成的 express 基本结构,所以有 app.js 文件,根据自身情况在合适的位置添加解析中间件。

app.js 文件内容如下:

var express = require('express');
...
// 用于将客户端发送过来的 JWT 字符串,解析还原成 JSON 对象的包
const expressJWT = require('express-jwt');
const secretKey = 'abcd';  // secret 密钥

var usersRouter = require('./routes/users'); // 普通用户
var adminRouter = require('./routes/admin'); // 管理员

var app = express();
...
// 用来解析 Token 的中间件(此处使用 unless 排除以 /api 开头的请求)
app.use(expressJWT.expressjwt({secret: jwt_config.secretKey,algorithms: ['HS256']}).unless({path: [/^\/api\//]}));
// 异常处理
app.use((err,req,res,next) => {
    console.log(err);
})

app.use('/api/users', usersRouter);
app.use('/admin', adminRouter);

module.exports = app;
3、获取管理员信息(admin)

routes/admin.js 文件中实现管理员相关功能:

var express = require('express');
var router = express.Router();

router.get('/getInfo', async function (req, res, next) {
    console.log(req.auth);
    res.send('hello admin');
})

module.exports = router;

前端 vue3 发送请求:

// admin 相关 API 
export const getAdminInfo = () => {
    return axios({
        url: baseUrl + '/admin/getInfo',
        method: 'get',
        headers: {
            // userToken:用户登录成功后接收的 token 参数
            Authorization: `Bearer ${userToken}`,
        }
    })
}