React前端+Django后端的MSAL认证架构搭建咨询
MSAL 前后端分离(React+Django)认证实践指南
一、标准实践与客户端类型选择
前后端分离场景下,微软官方的标准实践是前端用Public Client(MSAL.js),后端用Confidential Client(MSAL for Python),两者各司其职,缺一不可:
- 前端作为Public Client:无法安全存储客户端密钥,仅负责处理用户交互类认证流程(如登录弹窗、重定向),获取用户ID Token(用于前端身份状态管理)和针对你的Django API的Access Token(受众为你的API客户端ID)。
- 后端作为Confidential Client:可安全存储客户端密钥,核心职责是验证前端传来的Access Token,以及通过On-Behalf-Of(OBO)流程代表用户调用MS Graph API(或用应用权限直接调用Graph,无需用户上下文)。
所以必须同时使用两种客户端,不存在“可选”的情况,二者角色完全互补。
二、核心需求的实现方案
针对你需要的两种令牌,具体实现路径如下:
- 获取API访问令牌:前端通过MSAL.js完成用户登录,请求
api://<你的Django API客户端ID>/access_as_user这类自定义scope,拿到的Access Token受众即为你的API客户端ID。每次调用Django API时,将该令牌放在Authorization: Bearer <token>请求头中。 - 获取Graph访问令牌:后端通过OBO流程,用前端传来的API Access Token作为断言,向Azure AD请求针对Graph的Access Token。该流程的核心是让后端“代表”用户调用Graph,既保证权限合法性,又避免前端直接持有Graph令牌带来的泄露风险。
三、令牌缓存冗余问题
你当前两端都集成MSAL导致的双缓存确实冗余,完全没必要:
- 前端只需维护用户的ID Token(身份状态)和API Access Token的缓存,用于前端页面权限控制和API请求。
- 后端无需维护与前端重复的用户级令牌缓存,而是通过OBO流程动态获取Graph令牌;后端MSAL客户端可维护应用级缓存(如OBO获取的刷新令牌),但这是后端专属的、非重复的缓存。
四、“二选一”的误区
不存在只在一端实现MSAL的可行方案:
- 仅前端实现:后端无法安全验证令牌(前端传来的令牌可能被篡改),也无法安全调用Graph(前端的Graph令牌易泄露,且无法处理需后端权限的场景)。
- 仅后端实现:前端无法处理用户交互登录(后端是Confidential Client,不支持浏览器端OAuth流程),用户体验极差,完全违背前后端分离的架构设计。
必须两端配合,各司其职,不存在“二选一”的选项。
五、具体架构搭建步骤
前端(React + MSAL.js)
- 在Azure AD注册Public Client应用:设置重定向URI为你的前端地址(如
http://localhost:3000/auth-callback),添加针对Django API的delegated权限(需先注册你的API应用并暴露对应scope)。 - 初始化MSAL实例:配置租户ID、客户端ID、重定向URI等核心参数。
- 实现登录逻辑:调用
loginRedirect或loginPopup方法,请求包含API scope的权限,登录成功后缓存ID Token和API Access Token。 - API请求拦截:所有向Django API的请求,自动在请求头添加
Authorization: Bearer ${accessToken}。
后端(Django + MSAL Python)
- 在Azure AD注册Confidential Client应用:生成并安全存储客户端密钥,添加MS Graph的delegated权限(如
Mail.Send),并确保该应用被授权访问你的Django API。 - 令牌验证中间件:编写Django中间件,验证前端传来的Access Token:
- 检查令牌的
aud声明是否为你的API客户端ID; - 检查
iss声明是否为你的租户ID对应的Azure AD issuer; - 通过Azure AD的JWKS端点获取公钥,验证令牌签名的有效性。
- 检查令牌的
- 实现OBO流程:当需要调用Graph时,使用MSAL Python的
acquire_token_on_behalf_of方法,传入前端的API Access Token和Graph的scope(如https://graph.microsoft.com/Mail.Send),获取Graph Access Token后调用Graph API。 - 缓存优化:后端MSAL客户端可配置缓存,存储OBO流程获取的刷新令牌,减少重复请求Azure AD的次数。
关键注意事项
- 绝对禁止前端直接请求Graph的scope并持有Graph令牌,前端是Public Client,令牌暴露在浏览器中存在泄露风险。
- OBO流程需确保前端的API Access Token包含足够的
scp声明,允许后端代表用户调用Graph。 - 后端的客户端密钥必须通过环境变量、密钥管理服务等方式安全存储,禁止硬编码在代码中。
- 令牌验证必须在后端完成,前端的验证仅作为用户体验优化,不能作为安全校验的依据。
内容的提问来源于stack exchange,提问作者TheSlant
相关产品推荐
相关产品推荐

