如何验证React发送到Node.js的Azure AD令牌有效性?
问题描述
我基于微软React SPA示例代码修改了逻辑,将原本调用Microsoft Graph API的部分改为调用本地localhost:7000的后端接口,登录逻辑未做修改。前端通过MSAL获取令牌后传给后端:
前端获取令牌代码:
const { instance, accounts } = useMsal(); const [graphData, setData] = useState(null); function RequestProfileData() { // 静默获取访问令牌并附加到请求 instance .acquireTokenSilent({ ...loginRequest, account: accounts[0], }) .then((response) => { callMyEndpoint(response.accessToken).then(response => setData(response)); }); }
前端调用后端接口的函数:
export async function callMyEndpoint(accessToken) { const headers = new Headers(); const bearer = `Bearer ${accessToken}`; headers.append("Authorization", bearer); const options = { method: "POST", headers: headers, }; return fetch("http://localhost:7000/myendpoint", options) .then(response => response.json()) .catch(error => console.log(error)); }
后端Node.js接口已能获取请求头中的令牌,但需实现验证逻辑,确保仅Azure应用注册中的已登录用户可访问:
app.post("/myendpoint", async (req, res) => { console.log("TOKEN", req.headers.authorization); // 可正常打印令牌 // 此处需验证令牌有效性,如何实现? });
解决方案:验证Azure AD令牌有效性
推荐使用微软官方维护的express-oauth2-jwt-bearer库来完成令牌验证,它会自动处理签名校验、过期检查、受众匹配等核心逻辑,步骤如下:
1. 安装依赖
在后端项目中执行:
npm install express-oauth2-jwt-bearer
2. 准备Azure应用注册信息
从Azure门户的应用注册中获取以下参数:
- 租户ID:你的Azure AD租户唯一ID(格式如
xxxxxx-xxxx-xxxx-xxxx-xxxxxxxxx) - API客户端ID:后端API对应的应用注册ID(注意不是前端SPA的应用ID)
3. 配置验证中间件
引入库并创建验证中间件:
const { auth } = require('express-oauth2-jwt-bearer'); // 配置JWT验证规则 const validateAccessToken = auth({ issuerBaseURL: 'https://login.microsoftonline.com/你的租户ID/v2.0', audience: '你的后端API客户端ID', // 必须与前端请求令牌时的scope对应受众一致 });
4. 保护目标接口
将中间件添加到需要验证的接口上,只有验证通过的请求才能进入业务逻辑:
app.post("/myendpoint", validateAccessToken, async (req, res) => { // 令牌验证通过后执行此处逻辑 // 可通过req.auth.payload获取令牌解析后的用户信息(如用户ID、租户ID、角色等) console.log("验证通过的用户信息:", req.auth.payload); // 后续业务处理 res.json({ message: "访问成功", userInfo: req.auth.payload }); });
额外注意事项
- 确保前端请求令牌时的
scope包含后端API的权限(例如api://后端客户端ID/access_as_user),否则令牌的aud(受众)字段不匹配,会导致验证失败。 - 若需更细粒度的权限控制(如检查用户所属组、角色),可在验证通过后,通过
req.auth.payload.groups或req.auth.payload.roles字段做二次判断。
内容的提问来源于stack exchange,提问作者user346206
相关产品推荐
相关产品推荐

