You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

登录后签发JWT但中间件无法获取Authorization请求头问题

JWT验证中间件无法获取Authorization请求头问题排查与解决

问题描述

实现登录接口后,登录成功会签发JWT并返回用户信息,但在JWT验证中间件中,req.headers['authorization']始终为undefined,打印整个req.headers也找不到该字段,导致无法完成Token验证。

原登录接口代码

const login = require("express").Router();
const signUpTemplate = require('../src/Backend/SignupModel')
const bcrypt = require('bcrypt')
const jwt = require('jsonwebtoken');
login.post("/login", async function (request, response) {
    try{
        const {Email,password} = request.body
        console.log({Email,password});
        console.log('before finding');
        signUpTemplate.findOne({Email:Email}).then(async (user) => {
            if(!user){
                console.log('found user');
                console.log('username/password is not exist');
                response.status(400).send({msg:"username/password is not exist"})
            }
            else{
                if(await bcrypt.compare(password, user.password)){
                    const token = jwt.sign(
                        { user_id: user.id, Email },
                        process.env.TOKEN_KEY,
                        {
                          expiresIn: "2h",
                        }
                    );
                    user.token = token;
                    response.status(200).json(user);
                }
                else{
                    console.log('username/password is not exist');
                    response.status(400).send({msg:"username/password is not exist"})
                }
            }
        })
    }
    catch(e){
        console.error(e);
    }
});
module.exports = login;

原JWT验证中间件代码

const verifyJwt = (req,res,next) => {
    console.log('entered middle');
    console.log(req.headers);
    console.log(req.headers['authorization']);
    // const authHeader = req.headers['authorization'];
    // if (!authHeader) return res.sendStatus(401);
    return res.status(200).send('test works');
}

module.exports = verifyJwt

可能原因与解决方法

1. 前端未正确携带Authorization头

这是最常见的问题,登录成功后前端必须将Token以Bearer <token>的格式放在请求头的Authorization字段中发送。

示例(Axios):

axios.get('/protected-api', {
  headers: {
    'Authorization': `Bearer ${登录返回的token}`
  }
})

2. 跨域(CORS)配置缺失

如果前后端跨域,后端未配置允许携带自定义头,浏览器会拦截Authorization头,导致后端接收不到。

在Express中配置CORS:

const cors = require('cors');
app.use(cors({
  origin: '你的前端域名', // 例如http://localhost:3000
  allowedHeaders: ['Authorization', 'Content-Type'],
  credentials: true
}));

3. Express中间件顺序错误

验证中间件必须在express.json()等请求体解析中间件之后挂载,否则可能导致头信息未被正确解析。同时要确保中间件应用到需要验证的路由上:

const express = require('express');
const app = express();
const verifyJwt = require('./verifyJwt');
const loginRouter = require('./login');

// 先解析请求体
app.use(express.json());
// 挂载登录路由
app.use('/api/auth', loginRouter);
// 对需要验证的路由应用中间件
app.use('/api/protected', verifyJwt, (req, res) => {
  res.send('访问受保护资源成功');
});

4. 头字段大小写兼容问题

Node.js的req.headers会自动将所有请求头转为小写,因此直接使用req.headers.authorization更稳妥,避免大小写不一致的问题:

const verifyJwt = (req,res,next) => {
    console.log('entered middle');
    console.log(req.headers);
    const authHeader = req.headers.authorization;
    if (!authHeader) return res.sendStatus(401);
    // 提取Token(注意Bearer与Token之间的空格)
    const token = authHeader.split(' ')[1];
    // 执行JWT验证逻辑
    jwt.verify(token, process.env.TOKEN_KEY, (err, decoded) => {
        if (err) return res.sendStatus(403);
        req.user = decoded;
        next();
    });
}

额外:修复登录接口的异步逻辑问题

原登录接口混合使用async/await和.then(),易导致潜在错误,建议统一使用async/await:

login.post("/login", async function (request, response) {
    try{
        const { Email, password } = request.body;
        console.log({ Email, password });
        const user = await signUpTemplate.findOne({ Email: Email });
        
        if(!user){
            console.log('用户不存在');
            return response.status(400).send({ msg: "用户名/密码不存在" });
        }

        const isPasswordMatch = await bcrypt.compare(password, user.password);
        if (isPasswordMatch) {
            const token = jwt.sign(
                { user_id: user.id, Email },
                process.env.TOKEN_KEY,
                { expiresIn: "2h" }
            );
            user.token = token;
            return response.status(200).json(user);
        } else {
            console.log('密码不匹配');
            return response.status(400).send({ msg: "用户名/密码不存在" });
        }
    } catch(e) {
        console.error(e);
        return response.status(500).send({ msg: "服务器内部错误" });
    }
});

内容的提问来源于stack exchange,提问作者Amit Hadad

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 08:20:26