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

.NET 8 Blazor AUTO防伪令牌未渲染致登出失败求助

问题:Blazor Auto中MainLayout调用StateHasChanged导致登出防伪令牌失效

环境与背景

  • 基于.NET 8 Blazor Auto开发,包含服务端和客户端两个项目,所有组件及MainLayout均位于客户端项目
  • 需求:在MainLayout中加载所有页面共用的通用数据

问题现象

在MainLayout的OnAfterRenderAsync方法中添加数据获取逻辑并调用StateHasChanged()后,登出功能出现防伪令牌验证错误,浏览器渲染的登出表单中缺失__RequestVerificationToken隐藏字段;将数据获取逻辑移至各个页面并删除MainLayout中的StateHasChanged()调用后,登出功能恢复正常。

相关代码

客户端实际渲染的登出表单(浏览器输出)

<form action="Account/Logout" method="post" b-u3usycoz9l="">
    <input type="hidden" name="ReturnUrl" value="" b-u3usycoz9l="">
    <button type="submit" class="btn btn-link" b-u3usycoz9l=""><i class="fa-light fa-right-from-bracket" b-u3usycoz9l=""></i> Sign out
    </button>
</form>

MainLayout数据获取代码

protected override async Task OnAfterRenderAsync(bool firstRender)
{
    if (firstRender)
    {
        // 从服务获取通用数据

        Loading = false;
        StateHasChanged();
    }
}

登出组件代码

<Authorized>
    <div class="nav-item px-3">
        <form action="Account/Logout" method="post">
            <AntiforgeryToken />
            <input type="hidden" name="ReturnUrl" value="@currentUrl" />
            <button type="submit" class="nav-link">
                <span class="bi bi-arrow-bar-left-nav-menu" aria-hidden="true"></span> Logout
            </button>
        </form>
    </div>
</Authorized>

服务端Program.cs配置

app.UseAuthentication();
app.UseAuthorization();

app.UseAntiforgery();

报错信息

AntiforgeryValidationException: The required antiforgery request token was not provided in either form field "__RequestVerificationToken" or header value "RequestVerificationToken".
Microsoft.AspNetCore.Antiforgery.DefaultAntiforgery.ValidateRequestAsync(HttpContext httpContext)

BadHttpRequestException: Invalid anti-forgery token found when reading parameter "string returnUrl" from the request body as form.
Microsoft.AspNetCore.Http.RequestDelegateFactory+Log.InvalidAntiforgeryToken(HttpContext httpContext, string parameterTypeName, string parameterName, Exception exception, bool shouldThrow)

解决方案

原因分析

Blazor Auto的AntiforgeryToken组件依赖服务器端初始渲染上下文生成令牌。在OnAfterRenderAsync中调用StateHasChanged()会触发客户端二次渲染,此时已脱离服务器端的初始渲染流程,导致AntiforgeryToken无法正确生成并注入到表单中。

修复步骤

  1. 迁移数据获取至OnInitializedAsync方法
    OnInitializedAsync属于组件初始化阶段,在服务器端渲染流程内执行,状态更新不会破坏防伪令牌的生成上下文,且无需手动调用StateHasChanged():

    protected override async Task OnInitializedAsync()
    {
        // 从服务获取通用数据
    
        Loading = false;
    }
    
  2. 若必须使用OnAfterRenderAsync

    • 确保仅在非初始渲染场景下触发状态更新,或分离通用数据加载逻辑,等待AntiforgeryToken完成服务器端渲染后再执行
    • 使用InvokeAsync(StateHasChanged)确保线程安全,但仍优先推荐使用OnInitializedAsync方案
  3. 验证服务端防伪配置
    确认app.UseAntiforgery()位于app.UseAuthentication()和app.UseAuthorization()之后,且服务注册中已包含builder.Services.AddAntiforgery()(Blazor Auto默认已配置)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 13:25:01