Azure静态Web应用部署后JWT签名验证失败问题咨询
问题描述
我有一个以Azure Functions作为API后端的Azure静态Web应用。用户登录时通过以下代码生成JWT Token:
function generateToken(user: User): string{ const secretKey = process.env.SECRET_KEY; const tokenData = { userId: user.id, } const tokenOptions = { expireIn: "2 days" } const token = jwt.sign(tokenData, process.env.SECRET_KEY, tokenOptions); return token; }
但调用其他函数时,jwt.verify抛出无效签名错误,验证代码如下:
try{ const token = req.headers.authorization?.split(' ')[1]; jwt.verify(token, process.env.SECRET_KEY, {algorithms: ['HS256']}); }catch(tokenError){ context.res = { status: 401, body: `tokenError: ${tokenError}\n token: ${req.headers.authorization?.split(' ')[1]}\n decode: ${JSON.stringify(jwt.decode(req.headers.authorization?.split(' ')[1]))}\n ` }; return; }
本地运行完全正常,但部署到Azure后,Token的Payload从自定义内容:
{"userId":2,"iat":1701863111,"exp":1702035911}
变成了Azure系统生成的Token:
{"nbf":1701863176,"exp":1701863476,"iat":1701863176,"iss":"https://5de6fdb8-19cf-4d6e-9fd0-50a67c40ca59.scm.azurewebsites.net","aud":"https://5de6fdb8-19cf-4d6e-9fd0-50a67c40ca59.azurewebsites.net/azurefunctions"}
已确认Azure Functions能正常访问环境变量,也调整过generateToken的设置,请问问题原因是什么?
问题原因及解决方案
核心原因
部署后你的API收到的并非自己生成的自定义Token,而是Azure Functions集成的Easy Auth(简易认证)机制自动注入的系统Token。
当Azure静态Web应用与Azure Functions集成时,默认会启用Easy Auth,这个机制会在请求到达你的函数代码之前拦截请求,自动添加Azure自身的JWT Token到Authorization头中,直接覆盖了前端发送的你自定义生成的Token,导致jwt.verify用你的密钥验证Azure的系统Token,自然会出现无效签名错误。
解决步骤
- 调整Azure静态Web应用的认证规则:进入Azure门户,找到你的静态Web应用,在左侧菜单的「认证」选项中,配置路由排除规则,将登录接口(生成Token的接口)和需要自定义Token验证的API路由加入排除列表,让这些路由跳过Easy Auth的拦截。
- 修改Azure Functions的授权级别:在Azure Functions的函数配置中,将目标函数的授权级别从「函数」改为「匿名」。这样Easy Auth不会强制对这些函数进行认证拦截,你的自定义Token才能正常传递到函数代码中。
- 验证请求头传递:确认前端请求的
Authorization头确实携带了你生成的Bearer Token,部分场景下Easy Auth会修改请求头,若遇到这种情况,可在静态Web应用的配置中添加允许传递自定义请求头的规则,或者将自定义Token放在其他请求头(如X-Custom-Token)中传递,在函数代码中读取该头进行验证。
内容的提问来源于stack exchange,提问作者M4rkb0
相关产品推荐
相关产品推荐

