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

ASP.NET Core Web API谷歌认证遭遇CORS跨域错误求助

解决ASP.NET Core Web API谷歌认证的CORS拦截问题

问题根源

你遇到的核心问题是:OAuth2认证的重定向流程不适合通过AJAX请求发起。当React用GET请求调用/api/auth/signin-google时,API会返回重定向到谷歌认证页面的响应,但浏览器会因为谷歌的认证页面没有配置允许localhost:3000的CORS头,直接拦截这个跨域重定向响应,触发CORS错误。而直接在浏览器访问端点时,是浏览器发起的顶级导航,不受CORS规则限制,所以能正常跳转。

解决方案

方案1:直接让浏览器跳转(最简单)

不要用AJAX请求登录端点,而是让React直接触发浏览器的顶级导航到API的认证端点:

// React登录按钮点击事件处理
const handleGoogleLogin = () => {
  window.location.href = 'https://localhost:5278/api/auth/signin-google';
};

这样浏览器会直接跳转到谷歌认证页面,完成后回调回API,整个流程符合OAuth2的设计逻辑,不会触发CORS问题。

方案2:用弹出窗口处理认证(保留前端交互)

如果不想离开当前页面,可以用弹出窗口打开认证端点,认证完成后通过postMessage通知主页面:

React代码示例

const handleGoogleLogin = () => {
  const authWindow = window.open(
    'https://localhost:5278/api/auth/signin-google',
    '_blank',
    'width=600,height=600'
  );

  // 监听弹出窗口的消息
  const messageListener = (event) => {
    if (event.origin === 'https://localhost:5278') {
      if (event.data.type === 'AUTH_SUCCESS') {
        // 处理登录成功逻辑,比如获取用户信息
        console.log('登录成功', event.data.user);
        authWindow.close();
        window.removeEventListener('message', messageListener);
      }
    }
  };

  window.addEventListener('message', messageListener);
};

API回调端点修改

在API的谷歌认证回调端点中,添加返回一个HTML页面,通过postMessage通知父窗口:

[HttpGet("signin-google-callback")]
public async Task<IActionResult> GoogleCallback()
{
    var result = await HttpContext.AuthenticateAsync(GoogleDefaults.AuthenticationScheme);
    if (!result.Succeeded)
    {
        // 处理认证失败
        return Content("<script>window.opener.postMessage({type: 'AUTH_FAILURE'}, '*'); window.close();</script>", "text/html");
    }

    // 获取用户信息
    var user = result.Principal;
    var userData = new {
        Id = user.FindFirstValue(ClaimTypes.NameIdentifier),
        Name = user.FindFirstValue(ClaimTypes.Name),
        Email = user.FindFirstValue(ClaimTypes.Email)
    };

    // 返回HTML页面,发送消息给父窗口
    return Content($@"
        <script>
            window.opener.postMessage({{
                type: 'AUTH_SUCCESS',
                user: {JsonSerializer.Serialize(userData)}
            }}, 'https://localhost:3000');
            window.close();
        </script>", "text/html");
}

额外检查:API的CORS配置

虽然核心问题不是CORS配置,但确保你的API已经正确配置了允许前端域名:

// Program.cs中的CORS配置
builder.Services.AddCors(options =>
{
    options.AddPolicy("AllowReactApp", policy =>
    {
        policy.WithOrigins("https://localhost:3000")
              .AllowAnyHeader()
              .AllowAnyMethod()
              .AllowCredentials(); // 如果需要带cookie的话
    });
});

// 在UseAuthentication和UseAuthorization之前添加UseCors
app.UseCors("AllowReactApp");
app.UseAuthentication();
app.UseAuthorization();

关键提醒

OAuth2的授权码流程(Authorization Code Flow)是为浏览器顶级导航设计的,不要用AJAX请求发起认证跳转,这违背了OAuth2的设计初衷,也会触发浏览器的CORS限制。

内容的提问来源于stack exchange,提问作者Shagragada

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 20:40:08