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

.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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 11:43:18