ASP.NET Core React模板集成Azure AD认证授权 如何在React端实现登录登出
问题原因
你手动拼接URL访问不到Account控制器,大概率是漏了注册Microsoft Identity UI的服务和路由,这个是Microsoft.Identity.UI包自动生成的Area,不会默认注册,需要手动配置。
后端配置修正
先确认Startup.cs的配置正确:
- 配置服务阶段注册Identity UI:
public void ConfigureServices(IServiceCollection services) { // 你的其他身份配置,比如AddMicrosoftIdentityWebApp等 services.AddControllersWithViews(); // 必须加这行注册Microsoft Identity的内置控制器 services.AddRazorPages().AddMicrosoftIdentityUI(); // CORS配置要明确允许你的SPA域名,开启凭证支持 services.AddCors(options => { options.AddPolicy("AllowSPA", policy => { policy.WithOrigins("https://localhost:5000") .AllowAnyHeader() .AllowAnyMethod() .AllowCredentials(); }); }); }
- 配置中间件阶段注册路由:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { // 把静态文件中间件放到授权中间件前面,避免SPA静态资源被拦截,解决直接访问SPA报错的问题 app.UseStaticFiles(); app.UseRouting(); app.UseCors("AllowSPA"); app.UseAuthentication(); app.UseAuthorization(); app.UseEndpoints(endpoints => { endpoints.MapControllers(); // 必须加这行映射Razor Pages路由,内置的Account控制器才会生效 endpoints.MapRazorPages(); // 你的SPA fallback路由 endpoints.MapFallbackToFile("index.html"); }); }
React端实现登录登出
内置Account控制器的固定路由前缀为/MicrosoftIdentity/Account,你可以直接用普通a标签跳转对应地址,也可以添加跳转参数控制登录/登出后的回调地址。
示例导航组件代码
import { useState, useEffect } from 'react'; const Navbar = () => { const [userInfo, setUserInfo] = useState(null); // 页面加载时获取当前登录状态 useEffect(() => { // 你需要先在后端写一个简单的接口/api/user,返回当前登录用户的名称、ID等信息 // 必须携带credentials,浏览器才会自动带上身份cookie fetch('/api/user', { credentials: 'include' }) .then(res => { if (res.ok) return res.json(); return null; }) .then(data => setUserInfo(data)); }, []); return ( <ul className="navbar-nav"> {userInfo ? ( <> <li className="nav-item"> <span className="navbar-text text-dark">Hello {userInfo.name}!</span> </li> <li className="nav-item"> <a className="nav-link text-dark" href="/MicrosoftIdentity/Account/SignOut?post_logout_redirect_uri=https://localhost:5000" > 登出 </a> </li> </> ) : ( <li className="nav-item"> <a className="nav-link text-dark" href="/MicrosoftIdentity/Account/SignIn?redirectUri=https://localhost:5000" > 登录 </a> </li> )} </ul> ); }; export default Navbar;
注意事项
- 所有向后端发起的请求都要开启凭证携带:如果用fetch加
credentials: 'include',如果用axios加withCredentials: true,否则身份cookie不会被携带,会一直判定为未登录。 - 不要用前端路由跳转(比如react-router的
navigate)访问登录登出地址,必须用原生a标签跳转或者修改window.location.href,因为需要跳转到微软登录页完成身份校验。
内容的提问来源于stack exchange,提问作者Vivere
相关产品推荐
相关产品推荐

