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

.NET 8 Blazor Server中Google登录按钮报错:OAuth状态缺失

解决Blazor Server自定义Google登录按钮的OAuth State无效问题

问题根源

你遇到的AuthenticationFailureException: The oauth state was missing or invalid错误,核心原因是:ASP.NET Core的Google OAuth中间件依赖state参数防止CSRF攻击——当发起登录请求时,中间件会生成随机state并存储在用户会话中,Google回调时会验证该state是否匹配。而你直接使用Google官方GSI按钮跳转至signin-google回调地址,跳过了中间件生成state的步骤,导致回调时state缺失或不匹配。

解决方案

直接复用Identity脚手架生成的Google登录端点,该端点会自动处理state的生成与验证,和Identity登录页的逻辑完全一致。

修改后的LoginDisplay.razor代码

@inject IHttpContextAccessor ContextAccessor

<CascadingAuthenticationState>
    <AuthorizeView>
        <Authorized>
            <a href="Identity/Account/Manage">Hello, @context.User.Identity?.Name!</a>
            <a href="Identity/Account/Logout">Log out</a>
        </Authorized>
        <NotAuthorized>
            <a href="Identity/Account/Register">Register</a>
            <a href="Identity/Account/Login">Log in</a>
            
            <!-- 替换原GSI按钮为指向Identity Google登录端点的链接 -->
            <a href="/Identity/Account/Login?provider=Google" class="google-signin-btn">
                <img src="https://www.gstatic.com/images/branding/googlelogo/svg/googlelogo_clr_74x24px.svg" alt="Google" />
                <span>Sign in with Google</span>
            </a>
        </NotAuthorized>
    </AuthorizeView>
</CascadingAuthenticationState>

@code
{
    protected override async Task OnInitializedAsync()
    {
        var x = ContextAccessor.HttpContext.User;
        var xIdentity = x.Identity;
    }
}

<style>
.google-signin-btn {
    display: inline-flex;
    align-items: center;
    margin-left: 8px;
    padding: 8px 16px;
    border: 1px solid #dadce0;
    border-radius: 4px;
    background: white;
    color: #3c4043;
    text-decoration: none;
    font-family: Roboto, sans-serif;
    font-size: 14px;
    gap: 8px;
}
.google-signin-btn:hover {
    background: #f8f9fa;
    border-color: #dadce0;
}
</style>

原理说明

点击这个自定义按钮时,会跳转到Identity的/Identity/Account/Login?provider=Google端点,该端点会:

  1. 生成合法的state参数并存储到用户会话
  2. 自动跳转至Google的授权页面
  3. Google回调后,中间件会验证state的有效性,完成登录流程

进阶方案(如需保留GSI原生按钮)

如果必须使用Google GSI的原生按钮(如需要一键登录功能),需后端提供生成认证URL的接口:

  1. 添加后端接口生成带state的Google授权URL
[AllowAnonymous]
[HttpGet("api/get-google-auth-url")]
public IActionResult GetGoogleAuthUrl()
{
    var properties = new AuthenticationProperties { RedirectUri = "/" };
    return Challenge(properties, GoogleDefaults.AuthenticationScheme);
}
  1. 前端通过JavaScript调用该接口,获取跳转URL后设置给GSI按钮的data-login_uri,或直接跳转。

内容的提问来源于stack exchange,提问作者Wizard Of Loneliness

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 23:35:10