NodeJS Express框架中如何在中间件内发起API调用
实现方案
首先别在中间件里发本地HTTP请求调用自己的/login接口,属于多此一举的做法:平白多走一遍完整的HTTP请求处理链路,额外增加性能开销,错误处理也更麻烦。
正确的实现思路是把登录路由里的账号密码校验逻辑抽离成独立的可复用函数,让登录接口和密码校验中间件共同调用,完全避免重复代码。
步骤1:抽离公共校验逻辑
先把原本写在/login路由处理函数里的密码校验逻辑单独拆出来,放到公共工具文件里,比如新建utils/auth.js:
// utils/auth.js /** * 校验用户账号密码是否匹配 * @param {string} login 用户登录账号 * @param {string} inputPassword 用户提交的明文密码 * @returns {Promise<object|boolean>} 校验通过返回对应用户信息,失败返回false */ async function verifyUserCredential(login, inputPassword) { // 这里放你原本写在/login路由里的校验逻辑: // 1. 根据传入的login查询数据库中对应的用户记录 // 2. 把用户传入的明文密码和数据库中存储的加密密码做比对 // 3. 校验不通过直接返回false,通过则返回查询到的用户对象 } module.exports = { verifyUserCredential }
步骤2:改造原有登录接口
抽离完成后,原来的登录路由直接调用这个公共方法即可,不需要重复写校验逻辑:
const { verifyUserCredential } = require('./utils/auth') router.post('/login', async (req, res) => { const { login, password } = req.body const user = await verifyUserCredential(login, password) if (!user) { return res.status(401).json({ msg: '账号或密码错误' }) } // 保留你原有的生成accessToken的逻辑 res.json({ accessToken }) })
步骤3:编写isPasswordCorrect中间件
中间件里直接调用刚才抽好的公共校验方法即可,注意密码一般是更新用户信息时随请求体提交的,当前用户的账号可以从前置登录态校验中间件挂载的req.user上获取,不需要让用户重复提交账号:
const { verifyUserCredential } = require('./utils/auth') const isPasswordCorrect = async (req, res, next) => { try { // 按你实际的参数传参位置取值,这里假设更新接口会在请求体里传currentPassword做二次校验 const { currentPassword } = req.body // req.user是前置登录态校验中间件解析token后挂载的当前登录用户信息 const userLogin = req.user.login const passCheck = await verifyUserCredential(userLogin, currentPassword) if (!passCheck) { return res.status(403).json({ msg: '密码验证失败,无法修改账户信息' }) } next() } catch (err) { next(err) } }
步骤4:给更新接口挂载中间件
在你开发的更新用户信息路由上,按顺序挂载登录态校验中间件、密码校验中间件即可:
// authMiddleware是你原本写的登录态校验中间件,负责解析accessToken挂载req.user router.put('/user/info', authMiddleware, isPasswordCorrect, (req, res) => { // 执行更新用户信息的数据库操作 res.json({ msg: '账户信息更新成功' }) })
如果你坚持要在中间件内直接调用现有/login路由(非常不推荐),可以用Node内置的http模块或者相关请求工具发本地请求,但这种做法性能差、可维护性低,完全没有必要,抽离公共函数是Express项目中复用逻辑的标准实践。
内容的提问来源于stack exchange,提问作者arrmani88
相关产品推荐
相关产品推荐

