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

Blazor Server渲染模式下调用HttpContext.SignInAsync后Cookie未生成

问题:Blazor Auto渲染模式下Server端登录Cookie不生效

我创建了一个采用Auto渲染模式+全局路由的Blazor新项目,默认包含服务器端和客户端两个项目,所有页面都放在客户端项目中,我在客户端里加了Login.razor页面。

这个Login页面通过HttpClient调用服务器端的WebApi验证凭据,验证通过后服务端会调用HttpContext.SignInAsync,API返回成功响应后就把用户重定向到主页。

服务器端API代码

[HttpPost("signin")]
public async Task<IActionResult> SignInAsync([FromForm] string username, [FromForm] string password)
{
    var user = await _userRepository.GetByNameAsync(username);
    if (user != null)
    {
        var passwordHash = await _userRepository.GetPasswordHashAsync(user.Id);
        if (passwordHash != null)
        {
            var passwordResult = _passwordHasher.VerifyPasswordHash(user, passwordHash, password);
            if (passwordResult == PasswordVerificationResult.Success)
            {
                var claimsIdentity = new ClaimsIdentity(GetClaims(user), CookieAuthenticationDefaults.AuthenticationScheme);
                await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, new ClaimsPrincipal(claimsIdentity));

                return Ok(user);
            }
        }
    }
}

登录页面初始代码

async Task LogInAsync()
{
    var content = new FormUrlEncodedContent(new[]
    {
        new KeyValuePair<string, string>("username", LoginInfo.Username),
        new KeyValuePair<string, string>("password", LoginInfo.Password)
    });

    var response = await HttpClient.PostAsync("api/users/signin", content);
    if (response.IsSuccessStatusCode)
    {
        // 从查询字符串提取returnUrl
        var uri = new Uri(NavigationManager.Uri);
        var queryParams = System.Web.HttpUtility.ParseQueryString(uri.Query);

        string returnUrl = GetQueryStringParameter("returnUrl");

        // 重定向到returnUrl
        NavigationManager.NavigateTo(returnUrl, true);
    }
    else
    {
        Console.WriteLine("Invalid credentials");
    }
}

问题现象

因为用了Auto渲染模式,页面初始加载是Server渲染模式。用户点击登录后,断点确认服务端已经执行完HttpContext.SignInAsync,页面也完成重定向,但浏览器里没创建登录Cookie,用户还是未授权状态,会被打回登录页。而重定向后页面重新加载,WASM完全加载,渲染模式切换成WASM,这时候再点登录按钮就一切正常,Cookie能正常创建。也就是说只有在Server渲染模式下,浏览器不会自动创建登录Cookie。

我知道这可能和Server渲染模式通过SignalR运行的机制有关,但不清楚具体原因。

临时解决方案(手动写入Cookie)

我尝试从响应头里拿Cookie手动写入浏览器,功能倒是实现了:

async Task LogInAsync()
{
    var content = new FormUrlEncodedContent(new[]
    {
        new KeyValuePair<string, string>("username", LoginInfo.Username),
        new KeyValuePair<string, string>("password", LoginInfo.Password)
    });

    var response = await HttpClient.PostAsync("api/users/signin", content);
    if (response.IsSuccessStatusCode)
    {
        if (response.Headers.Contains("Set-Cookie"))
        {
            var setCookieHeader = response.Headers.GetValues("Set-Cookie").FirstOrDefault();
            if (!string.IsNullOrEmpty(setCookieHeader))
            {
                // 手动向浏览器写入Cookie
                var cook = setCookieHeader.Split(";")[0];
                await JSRuntime.InvokeVoidAsync("eval", $"document.cookie = '" + cook + "';");
            }
        }

        // 从查询字符串提取returnUrl
        var uri = new Uri(NavigationManager.Uri);
        var queryParams = System.Web.HttpUtility.ParseQueryString(uri.Query);

        string returnUrl = GetQueryStringParameter("returnUrl");

        // 重定向到returnUrl
        NavigationManager.NavigateTo(returnUrl, true);
        //await JSRuntime.InvokeVoidAsync("eval", "window.location.href = '/';");
    }
    else
    {
        Console.WriteLine("Invalid credentials");
    }
}

但不确定这种手动写Cookie的方式是否合理,想知道正确的解决方案是什么。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 07:28:14