.NET Core 5 MVC谷歌外部登录报错及功能实现疑问
ASP.NET Core 5谷歌外部登录问题排查与解答
问题背景
在ASP.NET Core MVC中实现谷歌外部登录时,触发登录后提示Access blocked: This app’s request is invalid.,具体错误为Error 400: redirect_uri_mismatch,环境为.NET Core 5。
相关代码
ConfigureServices方法
public void ConfigureServices(IServiceCollection services) { services.AddControllersWithViews(); services.AddDbContext<App_DbContext>( optionsBuilder => { optionsBuilder.UseSqlServer(Configuration.GetConnectionString("MyConnection")); }); services.AddIdentity<ApplicationUser, IdentityRole>( options => { options.User.RequireUniqueEmail = true; options.Lockout.MaxFailedAccessAttempts = 4; options.Lockout.DefaultLockoutTimeSpan = new TimeSpan(0, 3, 0); options.Lockout.AllowedForNewUsers = true; options.Password.RequiredLength = 10; } ) .AddEntityFrameworkStores<App_DbContext>() .AddDefaultTokenProviders(); services.ConfigureApplicationCookie(CAO => { CAO.LoginPath = "/Account/SignIn"; CAO.Cookie.Name = "LoginCookie"; }); services.AddAuthentication() .AddGoogle(options => { IConfiguration googleSection = Configuration.GetSection("Authentication:Google"); options.ClientId = googleSection["ClientId"]; options.ClientSecret = googleSection["ClientSecret"]; }); }
谷歌认证相关Action
public IActionResult GoogleLogin() { AuthenticationProperties ap = new AuthenticationProperties { RedirectUri = Url.Action("GoogleResponse") }; return Challenge(ap,GoogleDefaults.AuthenticationScheme); } public async Task<IActionResult> GoogleResponse() { AuthenticateResult result = await HttpContext.AuthenticateAsync(GoogleDefaults.AuthenticationScheme); if (result.Succeeded) return RedirectToAction("Index"); return View(nameof(SignIn)); }
问题解答
1. 两个Action的作用
- GoogleLogin:启动谷歌外部认证流程。创建
AuthenticationProperties指定认证完成后的回调地址,通过Challenge方法将用户重定向到谷歌的授权登录页面,让用户完成谷歌账号的登录与授权。 - GoogleResponse:作为谷歌认证的回调处理Action。接收谷歌返回的认证结果,验证认证是否成功;如果成功则跳转到首页,失败则返回登录页面。
2. 导致功能失效的问题与缺失
- redirect_uri不匹配:这是直接触发Error 400的原因。谷歌开发者控制台中配置的「授权重定向URI」,必须和代码中
Url.Action("GoogleResponse")生成的地址完全一致,包括协议(HTTP/HTTPS)、域名、端口、完整路径。例如本地调试时地址可能是http://localhost:5000/Account/GoogleResponse,需要将这个地址准确添加到谷歌控制台的重定向URI列表中。 - 缺少本地会话持久化逻辑:当前
GoogleResponse中仅验证了谷歌认证结果,但没有将认证后的用户信息转换为本地系统的认证会话。即使谷歌认证成功,用户后续访问页面时依然会处于未登录状态。 - 潜在配置错误:需确认
appsettings.json中Authentication:Google节点下的ClientId和ClientSecret是否与谷歌开发者控制台中创建的应用信息完全一致。
3. 认证状态的维持机制
- 该外部登录最终通过Cookie认证维持用户的登录状态。负责此功能的代码包括:
services.AddIdentity<ApplicationUser, IdentityRole>(...):ASP.NET Core Identity默认集成了Cookie认证中间件,用于管理用户的本地认证会话。services.ConfigureApplicationCookie(...):配置应用级认证Cookie的参数,比如登录跳转路径、Cookie名称等。
- 但当前代码的
GoogleResponse中缺少关键步骤:需要在谷歌认证成功后,调用HttpContext.SignInAsync生成本地认证Cookie。示例修改如下:
public async Task<IActionResult> GoogleResponse() { AuthenticateResult result = await HttpContext.AuthenticateAsync(GoogleDefaults.AuthenticationScheme); if (result.Succeeded) { // 提取谷歌返回的用户信息,创建本地身份凭证 var claims = result.Principal.Claims.ToList(); var identity = new ClaimsIdentity(claims, IdentityConstants.ApplicationScheme); var principal = new ClaimsPrincipal(identity); // 生成本地认证Cookie,维持登录状态 await HttpContext.SignInAsync(IdentityConstants.ApplicationScheme, principal); return RedirectToAction("Index"); } return View(nameof(SignIn)); }
内容的提问来源于stack exchange,提问作者Hossam Zaki
相关产品推荐
相关产品推荐

