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
相关产品推荐
相关产品推荐

