尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
如何用 MSAL 在 Refine 中接入 Azure AD B2C 登录?
如何用 MSAL 在 Refine 中接入 Azure AD B2C 登录【免费下载链接】refineA React Framework for building internal tools, admin panels, dashboards B2B apps with unmatched flexibility.项目地址: https://gitcode.com/GitHub_Trending/re/refine假设你已经在用 Refine 做了一个内部管理应用现在不想再维护自己的账号密码而是让企业用户直接用 Azure AD B2C 的社交账号、企业账号或本地账号登录。目标结果是应用打开时先经过一个登录页点击按钮跳转到 Azure B2C 登录页登录成功后应用保存访问令牌并自动把它附加到后续的数据请求上。Refine 官方的 Azure AD 文档 走的就是这条路用 Microsoft Authentication LibraryMSAL的 JavaScript 版本azure/msal-browser加 React 辅助包azure/msal-react完成认证再由 Refine 的authProvider接管登录态判断。文档以 Azure AD B2C 为例并说明用普通 Azure AD 做认证的步骤与之非常相似。下面按文档给出的顺序逐步接入。代码示例基于 antd UI 集成refinedev/antd和refinedev/react-router路由。安装 MSAL 依赖在 Refine 项目根目录安装两个包三个包管理器任选其一# npm npm i azure/msal-browser azure/msal-react # pnpm pnpm add azure/msal-browser azure/msal-react # yarn yarn add azure/msal-browser azure/msal-react这两个包分别提供 MSAL 的浏览器端实现PublicClientApplication、事件回调等和 React 集成MsalProvider、useMsal、useIsAuthenticated等 hook。创建 MSAL 配置文件在src/config.ts中创建 MSAL 配置。文档给出的完整内容如下其中带YOUR_前缀的字符串是占位符需要替换为你自己在 Azure 租户中申请到的值每个占位符对应的环境变量写法文档已用注释保留在代码里按注释中的写法接入自己的环境变量即可import { Configuration, LogLevel } from azure/msal-browser; export const msalConfig: Configuration { auth: { clientId: YOUR_CLIENT_ID, //${process.env.REACT_APP_AZURE_AAD_CLIENT_ID}, authority: YOUR_AUTHORITY, //https://${process.env.REACT_APP_AZURE_AAD_TENANT_NAME}.b2clogin.com/${process.env.REACT_APP_AZURE_AAD_TENANT_NAME}.onmicrosoft.com/${process.env.REACT_APP_AZURE_AAD_POLICY_NAME}, knownAuthorities: [YOUR_KNOWN_AUTHORITIES], //[${process.env.REACT_APP_AZURE_AAD_TENANT_NAME}.b2clogin.com], redirectUri: http://localhost:3000/, // Replace appropriately postLogoutRedirectUri: window.location.origin, }, cache: { cacheLocation: sessionStorage, // This configures where your cache will be stored storeAuthStateInCookie: false, // Set this to true if you are having issues on IE11 or Edge }, }; // Add scopes here for ID token to be used at Microsoft identity platform endpoints. export const loginRequest { scopes: [User.Read] }; export const tokenRequest { scopes: [...] // Replace ... with your custom scopes }; // Add the endpoints here for Microsoft Graph API services youd like to use. export const graphConfig { graphMeEndpoint: ENTER_THE_GRAPH_ENDPOINT_HERE/v1.0/me };几个需要替换或确认的位置clientId、authority、knownAuthorities来自你的 Azure B2C 租户与客户端应用注册。按代码注释中的环境变量形式拼接后authority形如https://tenant.b2clogin.com/tenant.onmicrosoft.com/policyknownAuthorities为tenant.b2clogin.com。redirectUri登录完成后跳回的地址文档示例为http://localhost:3000/注释要求按你的实际部署地址替换Replace appropriately。tokenRequest.scopes代码里的...是占位文档注释明确要求替换成你需要的自定义 scopes。graphConfig只有你要调用 Microsoft Graph API 时才需要按注释填入实际的 Graph 端点即可不需要 Graph 可以忽略这一节。文档建议用环境变量管理这些配置参数而不是把值直接写死在代码里。用 MsalProvider 包裹根组件修改src/index.tsx创建PublicClientApplication实例监听LOGIN_SUCCESS事件——登录成功后先静默获取访问令牌成功后写入localStorage静默获取失败时回退到弹窗方式获取。同时用MsalProvider包裹整个应用import React from react; import ReactDOM from react-dom/client; import { EventType, PublicClientApplication, AccountInfo, EventPayload, SilentRequest, } from azure/msal-browser; import { MsalProvider } from azure/msal-react; import App, { TOKEN_KEY } from ./App; import { msalConfig, tokenRequest } from ./config; const msalInstance new PublicClientApplication(msalConfig); msalInstance.addEventCallback(async (event) { if (event.eventType EventType.LOGIN_SUCCESS) { const payload: EventPayload event.payload; msalInstance.setActiveAccount(payload as AccountInfo); let account msalInstance.getActiveAccount(); const request: SilentRequest { ...tokenRequest, account: account!, }; try { // Silently acquires an access token which is then attached to a request for API access const response await msalInstance.acquireTokenSilent(request); console.log(Fetching access token: success); console.log(Scopes, response.scopes); console.log(Token Type, response.tokenType); localStorage.setItem(TOKEN_KEY, response.accessToken); } catch (e) { msalInstance.acquireTokenPopup(request).then((response) { localStorage.setItem(TOKEN_KEY, response.accessToken); }); } } }); const root ReactDOM.createRoot( document.getElementById(root) as HTMLElement, ); root.render( React.StrictMode MsalProvider instance{msalInstance} App / /MsalProvider /React.StrictMode, );这里TOKEN_KEY是从App.tsx导入的常量取值refine-auth后面保存令牌、读取令牌都通过它进行。覆盖 Refine 的登录页Refine 允许覆盖默认登录页。在src/下创建login.tsx用一个按钮触发useLogin()实际跳转由authProvider.login里的loginRedirect()完成import React from react; import { useLogin } from refinedev/core; import { Layout, Button } from antd; const LoginPage () { const SignInButton () { const { mutate: login } useLogin(); return ( Button typeprimary sizelarge block onClick{() login()} Sign in /Button ); }; return ( Layout style{{ background: radial-gradient(50% 50% at 50% 50%, #63386A 0%, #310438 100%), backgroundSize: cover, }} div style{{ height: 100vh, display: flex }} div style{{ maxWidth: 200px, margin: auto }} div style{{ marginBottom: 28px }} img src./refine.svg altRefine / /div SignInButton / /div /div /Layout ); }; export default LoginPage;编写 authProvider 与请求令牌注入核心在src/App.tsx定义AuthProvider让 Refine 的登录态完全由 MSAL 的账号和令牌驱动同时给 axios 实例加请求拦截器把localStorage中的令牌写进Authorization请求头import { Refine, AuthProvider, Authenticated } from refinedev/core; import { Layout, ErrorComponent } from refinedev/antd; import routerProvider, { NavigateToResource, CatchAllNavigate, } from refinedev/react-router; import dataProvider from refinedev/simple-rest; import { useIsAuthenticated, useMsal } from azure/msal-react; import { AccountInfo, SilentRequest } from azure/msal-browser; import axios from axios; import { BrowserRouter, Routes, Route, Outlet } from react-router; import LoginPage from ./login; import { tokenRequest } from ./config; export const TOKEN_KEY refine-auth; export const axiosInstance axios.create(); axiosInstance.interceptors.request.use( // Here we can perform any function wed like on the request (config) { // Retrieve the token from local storage const token localStorage.getItem(TOKEN_KEY); // Check if the header property exists if (config.headers) { // Set the Authorization header if it exists config.headers[Authorization] Bearer ${token}; } return config; }, ); const App: React.FC () { const API_URL https://api.fake-rest.refine.dev; const isAuthenticated useIsAuthenticated(); const { instance, inProgress, accounts } useMsal(); if (inProgress login || inProgress handleRedirect) { return divLoading.../div; } const account: AccountInfo accounts[0]; const request: SilentRequest { ...tokenRequest, account, }; const authProvider: AuthProvider { login: async () { instance.loginRedirect(); // Pick the strategy you prefer i.e. redirect or popup return { success: true, }; }, register: async () ({ success: true, }), resetPassword: async () ({ success: true, }), updatePassword: async () ({ success: true, }), logout: async () ({ success: true, }), check: async () { try { if (account) { const token await instance.acquireTokenSilent(request); localStorage.setItem(TOKEN_KEY, token.accessToken); return { authenticated: true, }; } else { return { authenticated: false, redirectTo: /login, }; } } catch (e) { return { authenticated: false, redirectTo: /login, }; } }, onError: async (error) { console.error(error); return { error }; }, getPermissions: async () null, getIdentity: async (): PromiseAccountInfo { if (account null || account undefined) { return null; } return account; }, }; return ( BrowserRouter Refine routerProvider{routerProvider} dataProvider{dataProvider(API_URL, axiosInstance)} authProvider{authProvider} resources{[ { name: posts, list: /posts, }, ]} Routes Route element{ Authenticated fallback{CatchAllNavigate to/login /} Layout Outlet / /Layout /Authenticated } Route path/posts element{divdummy list page/div} / /Route Route element{ Authenticated fallback{Outlet /} NavigateToResource / /Authenticated } Route path/login element{LoginPage /} / /Route Route path* element{ErrorComponent /} / /Routes /Refine /BrowserRouter ); }; export default App;各部分的作用login调用instance.loginRedirect()把浏览器跳转到 Azure B2C 登录页。注释说明也可以换成你偏好的策略redirect 或 popup。check这是登录态判断的核心。存在账号时静默获取令牌并写入localStorage返回authenticated: true没有账号或获取失败时返回authenticated: false并携带redirectTo: /login由Authenticated组件负责跳转。getIdentity直接返回当前AccountInfo供 UI 展示当前用户。路由结构受保护页面套在Authenticated里未登录时回退到/login/login页本身又包了一层Authenticated已登录用户访问它时会被NavigateToResource带回业务页。数据请求走dataProvider(API_URL, axiosInstance)文档示例中API_URL是https://api.fake-rest.refine.dev接入自己的后端时替换为你的 API 地址即可axiosInstance的拦截器保证每个请求自动带上Bearer令牌。register、resetPassword、updatePassword、logout在示例中统一返回success: true因为账号生命周期由 Azure B2C 侧管理应用内不做这些操作。验证接入是否生效文档代码中体现的验证点如下按流程核对应用启动时若 MSAL 正在执行login或handleRedirect页面显示Loading...说明重定向流程在走。未登录状态访问业务页面check返回未认证页面落到/login并出现 Sign in 按钮。点击 Sign in 后被重定向到 Azure B2C 登录页登录成功后LOGIN_SUCCESS回调触发静默获取令牌。文档示例在成功后打印的日志文档示例输出Fetching access token: success Scopes ... Token Type ...令牌以refine-auth为键存入localStorage后续经axiosInstance发出的请求Authorization头为Bearer token。已登录状态刷新页面check能静默拿到令牌并返回authenticated: true应用直接进入业务页而不是/login。限制与注意点示例的登录页和 App 基于 antdrefinedev/antd的Layout、ErrorComponent与refinedev/react-router使用其他 UI 包或路由集成时对应导入需要按各自的包调整MSAL 相关逻辑不变。文档以 Azure AD B2C 为例并说明认证普通 Azure AD 的步骤与之非常相似。redirectUri必须与浏览器中实际运行地址一致示例为本地开发地址http://localhost:3000/部署到别的环境时按代码注释替换。完整可核对的原始步骤见 documentation/docs/advanced-tutorials/auth/azure-ad.mdMSAL 各配置项的更多说明见 MSAL 官方文档。【免费下载链接】refineA React Framework for building internal tools, admin panels, dashboards B2B apps with unmatched flexibility.项目地址: https://gitcode.com/GitHub_Trending/re/refine创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
RELATED

相关推荐

Beads 的 MCP Server 集成指南:在无 Shell 环境中让 Coding Agent 使用 bd 管理任务

Beads 的 MCP Server 集成指南:在无 Shell 环境中让 Coding Agent 使用 bd 管理任务

Beads 的 MCP Server 集成指南:在无 Shell 环境中让 Coding Agent 使用 bd 管理任务 【免费下载链接】beads Beads - A memory upgrade for your coding agent 项目地址: https://gitcode.com/GitHub_Trending/beads1/beads Beads(bd)…

📅 2026/9/12 16:18:25
量化交易数据源怎么选?四个常用工具一张表对比

量化交易数据源怎么选?四个常用工具一张表对比

量化交易数据源怎么选?四个常用工具一张表对比 【免费下载链接】awesome-systematic-trading A curated list of awesome libraries, packages, strategies, books, blogs, tutorials for systematic trading. 项目地址: https://gitcode.com/GitHub_Trending/aw/…

📅 2026/9/12 16:13:25
HarmonyOS时间处理利器:Dayjs核心功能与集成实践

HarmonyOS时间处理利器:Dayjs核心功能与集成实践

1. HarmonyOS与Dayjs时间处理组件概述 在HarmonyOS应用开发中,时间处理是每个开发者都无法回避的基础需求。无论是用户界面的日期显示、数据存储时的时间戳记录,还是业务逻辑中的时间计算,都需要可靠的时间处理工具。然而原生HarmonyOS SDK在…

📅 2026/9/12 16:13:25
MORE NEWS

更多资讯

📰

SadTalker:1张照片生成说话视频,3步跑通AI口型同步

SadTalker:1张照片生成说话视频,3步跑通AI口型同步 【免费下载链接】SadTalker [CVPR 2023] SadTalker:Learning Realistic 3D Motion Coefficients for Stylized Audio-Driven Single Image Talking Face Animation 项目地址: https://git…

📰

SD卡文件系统开发:从协议到ESP32实战应用

1. SD卡记录文件查看技术概述SD卡作为嵌入式系统和移动设备中最常用的存储介质之一,其文件系统的访问与管理一直是开发者关注的重点。查看SD卡记录文件看似简单的操作,实际上涉及存储协议、文件系统、硬件接口等多个技术层面的协同工作。在ESP32、树莓派…

📰

51单片机PWM调光台灯设计:光敏电阻与ADC自动亮度控制

简介:一份基于STC89C52单片机的PWM调光台灯智能光照检测设计方案,面向单片机初学者、电子竞赛及课程设计人群,解决台灯自动感知环境光并分档调光的实际需求。系统支持自动与手动双模式,自动模式利用光敏电阻配合ADC0832采集外界光…

📰

无人超市系统设计:Spring Boot单体架构下的IoT业务闭环实现

简介:本资源是一套完整的Java毕业设计项目实战材料,面向计算机专业本科生及Spring Boot初学者,聚焦无人超市场景下的全栈开发实践。项目基于Spring Boot构建,涵盖商品管理、自助购物、支付结算、库存预警、会员积分、安防监控与销…

📰

如何用 runner-images 自建 GitHub Actions Runner 镜像:3 个场景跑通构建、裁剪与验证

如何用 runner-images 自建 GitHub Actions Runner 镜像:3 个场景跑通构建、裁剪与验证 【免费下载链接】runner-images GitHub Actions runner images 项目地址: https://gitcode.com/GitHub_Trending/ru/runner-images runner-images 是 GitHub 托管 Runne…

📰

Label Studio 标注一致性(Agreement)计算完整指南:Consensus 与 Pairwise 方法论、指标与权重配置

Label Studio 标注一致性(Agreement)计算完整指南:Consensus 与 Pairwise 方法论、指标与权重配置 【免费下载链接】label-studio Label Studio is a multi-type data labeling and annotation tool with standardized output format 项目地…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬