为何无法在Swagger中传递JWT令牌进行身份验证?
我在Swagger中发送JWT令牌进行身份验证,但服务端始终无法正确接收。现有/connect接口用于生成令牌,/clients/get接口在控制器中依赖该令牌做身份校验,但发送令牌后要么收到「无令牌」的提示,要么令牌值为null,完全无法正常响应。
我的Swagger配置
{ "swagger": "2.0", "info": { "title": "Documentation API", "version": "1.0.0", "description": "API pour un site de gestion de reservations pour 3 chambres d'hôtes chez un particulier." }, "servers": [ { "url": "http://localhost:5000/", "description": "Development server" } ], "paths": { "/clients/get": { "get": { "tags": ["Clients"], "description": "", "security": [{"Bearer": []}], "responses": { "200": {"description": "OK"}, "401": {"description": "Unauthorized"}, "404": {"description": "Not Found"} } } }, "/clients/connect": { "post": { "tags": ["Clients"], "description": "Connectez-vous en utilisant un email et un mot de passe.", "parameters": [ { "in": "formData", "name": "email", "type": "string", "required": true, "description": "Votre email" }, { "in": "formData", "name": "password", "type": "string", "required": true, "description": "Votre mot de passe" } ], "responses": { "200": {"description": "OK"}, "404": {"description": "Not Found"} } } } }, "securityDefinitions": { "Bearer": { "type": "apiKey", "name": "Authorization", "in": "header" } }, "security": {"Bearer": []} }
我已经尝试使用bearerAuth配置,但问题依旧。以下是/clients/get接口的控制器函数:
const findOneClients = async (req, res) => { try { const token = req.header('Authorization'); if (!token) { return res.status(401).send({ Error: 'Token JWT manquant dans l\'en-tête Authorization' }); } const decodedToken = jwt.verify( token.split(' ')[1], process.env.TOKEN_SECRET); const id = decodedToken.id; const client = await Client.findOne({ id: id }); if (!client) { return res.status(404).send({ Error: `Aucun client trouvé avec l'ID : ${id}` }); } // Decrypter adresse const decryptAdresse = crypto.AES.decrypt(client.adresse, process.env.CRYPTO_SECRET); client.adresse = decryptAdresse.toString(crypto.enc.Utf8); // Decrypter ville const decryptVille = crypto.AES.decrypt(client.ville, process.env.CRYPTO_SECRET); client.ville = decryptVille.toString(crypto.enc.Utf8); // Decrypter code postal const decryptCodePostal = crypto.AES.decrypt(client.codePostal, process.env.CRYPTO_SECRET); client.codePostal = decryptCodePostal.toString(crypto.enc.Utf8); // Decrypter telephone const decryptTelephone = crypto.AES.decrypt(client.telephone, process.env.CRYPTO_SECRET); client.telephone = decryptTelephone.toString(crypto.enc.Utf8); return res.status(200).json(client); } catch (e) { addLog("error", e, "client.controller.js"); } };
解决思路
修正Swagger全局安全配置格式
你的Swagger配置中顶级security字段格式错误,Swagger 2.0要求全局安全规则是数组格式,将:"security": {"Bearer": []}修改为:
"security": [{"Bearer": []}]格式错误会导致Swagger UI无法正确识别全局身份验证规则,进而无法自动携带Authorization头。
确保Swagger中令牌的输入格式正确
在Swagger UI的「Authorize」弹窗中输入令牌时,必须以Bearer为前缀(注意后面有空格),例如:Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MSwiaWF0IjoxNzE5MjQwNjYwfQ.S_example_token你的控制器代码中使用
token.split(' ')[1]提取令牌核心部分,如果缺少前缀,会导致split后获取到错误内容,甚至抛出异常。检查CORS中间件是否允许Authorization头
如果你的项目使用Express+CORS中间件,需要显式允许Authorization头传递,否则浏览器会拦截该请求头:const cors = require('cors'); app.use(cors({ allowedHeaders: ['Authorization', 'Content-Type'], exposedHeaders: ['Authorization'] }));调试请求头的实际传递情况
在控制器函数开头添加日志,打印完整的请求头,确认Authorization是否被正确传递:console.log('Received headers:', req.headers);如果日志中没有
authorization字段(注意Node.js中请求头会被转为小写),说明请求根本没携带该头,问题出在Swagger配置或发送方式;如果有,再检查格式是否符合Bearer <token>的要求。验证/connect接口的返回格式
确保/connect接口返回的是纯JWT字符串,而非带Bearer前缀的内容,例如返回:{ "token": "eyJhbGciOiJIUzI1Ni..." }前缀是需要在请求头中手动添加的,而非由接口返回。
内容的提问来源于stack exchange,提问作者Tom

