You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ASP.NET Core React模板集成Azure AD认证授权 如何在React端实现登录登出

问题原因

你手动拼接URL访问不到Account控制器,大概率是漏了注册Microsoft Identity UI的服务和路由,这个是Microsoft.Identity.UI包自动生成的Area,不会默认注册,需要手动配置。

后端配置修正

先确认Startup.cs的配置正确:

  1. 配置服务阶段注册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();
        });
    });
}
  1. 配置中间件阶段注册路由:
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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.06 00:36:02