React前端+Node.js后端的Azure AD身份验证配置咨询
React + Node.js 集成 Azure AD 最简实现
前端(React)部分
1. 安装依赖
npm install @azure/msal-react @azure/msal-browser axios
2. 初始化 MSAL 实例
在src/authConfig.js中配置:
import { PublicClientApplication } from '@azure/msal-browser'; export const msalInstance = new PublicClientApplication({ auth: { clientId: '你的前端客户端ID', authority: 'https://login.microsoftonline.com/你的租户ID', redirectUri: window.location.origin // 登录后跳转回当前页面 }, cache: { cacheLocation: 'sessionStorage', storeAuthStateInCookie: false } }); // 定义后端API的访问权限范围 export const apiConfig = { scopes: ['api://你的后端客户端ID/access_as_user'], // 后端注册时暴露的scope uri: 'http://localhost:3001/api/protected' // 后端接口地址 };
3. 用 MSALProvider 包裹应用
在src/index.js中:
import { MsalProvider } from '@azure/msal-react'; import { msalInstance } from './authConfig'; ReactDOM.render( <MsalProvider instance={msalInstance}> <App /> </MsalProvider>, document.getElementById('root') );
4. 实现登录/登出与令牌获取
在需要登录按钮的组件中:
import { useMsal, useIsAuthenticated } from '@azure/msal-react'; import { apiConfig } from '../authConfig'; import axios from 'axios'; function LoginComponent() { const { instance, accounts } = useMsal(); const isAuthenticated = useIsAuthenticated(); const handleLogin = async () => { await instance.loginPopup({ scopes: apiConfig.scopes }); }; const handleLogout = () => { instance.logoutPopup(); }; const callProtectedApi = async () => { // 获取访问令牌 const response = await instance.acquireTokenSilent({ account: accounts[0], scopes: apiConfig.scopes }); // 携带令牌发送请求 try { const res = await axios.get(apiConfig.uri, { headers: { Authorization: `Bearer ${response.accessToken}` } }); console.log('API响应:', res.data); } catch (err) { console.error('请求失败:', err); } }; if (isAuthenticated) { return ( <div> <p>已登录用户: {accounts[0].username}</p> <button onClick={handleLogout}>登出</button> <button onClick={callProtectedApi}>调用受保护接口</button> </div> ); } return <button onClick={handleLogin}>登录</button>; } export default LoginComponent;
后端(Node.js/Express)部分
1. 安装依赖
npm install express express-jwt jwks-rsa cors
2. 配置JWT验证中间件
在server.js中:
const express = require('express'); const jwt = require('express-jwt'); const jwksRsa = require('jwks-rsa'); const cors = require('cors'); const app = express(); app.use(cors()); app.use(express.json()); // 配置Azure AD验证参数 const tenantId = '你的租户ID'; const audience = 'api://你的后端客户端ID'; // 后端应用的客户端ID // 创建验证中间件 const validateAccessToken = jwt({ // 从Azure AD的JWKS端点获取公钥 secret: jwksRsa.expressJwtSecret({ cache: true, rateLimit: true, jwksRequestsPerMinute: 5, jwksUri: `https://login.microsoftonline.com/${tenantId}/discovery/v2.0/keys` }), audience: audience, issuer: `https://login.microsoftonline.com/${tenantId}/v2.0`, algorithms: ['RS256'] }); // 受保护的接口 app.get('/api/protected', validateAccessToken, (req, res) => { // req.user包含用户信息 res.json({ message: '访问受保护接口成功', user: { id: req.user.sub, username: req.user.preferred_username } }); }); // 公开接口(不需要验证) app.get('/api/public', (req, res) => { res.json({ message: '这是公开接口' }); }); app.listen(3001, () => { console.log('后端服务运行在http://localhost:3001'); });
关键注意事项
- 应用注册配置:
- 前端应用注册:添加"单页应用(SPA)"重定向URI,给后端API的
access_as_user权限(API权限 -> 添加权限 -> 我的API -> 选择后端API -> 勾选权限)。 - 后端应用注册:暴露API范围("公开API" -> 添加范围,比如
access_as_user),设置接受的令牌版本为V2。
- 前端应用注册:添加"单页应用(SPA)"重定向URI,给后端API的
- 令牌范围:前端请求的scope必须和后端暴露的一致,否则验证会失败。
- 环境变量:实际生产环境中,不要硬编码租户ID、客户端ID,用环境变量管理。
内容的提问来源于stack exchange,提问作者user346206
相关产品推荐
相关产品推荐

