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

Blazor Server应用OAuth授权码流重定向异常求助

解决Blazor Server OAuth授权码流跳转失败与路由循环问题

1. 修复Callback页面导航逻辑

Blazor Server中异步操作完成后的导航容易受客户端路由缓存影响,需强制重载并确保Token正确存储后再跳转:

@page "/Callback"
@inject NavigationManager Navigation
@inject DeviceService DeviceService
@inject OAuthService OAuthService

@code {
    protected override async Task OnInitializedAsync()
    {
        var uri = new Uri(Navigation.Uri);
        var code = uri.Query.Split("code=")[1].Split('&')[0];

        try
        {
            var token = await OAuthService.GetAccessTokenAsync(code);
            // 确保Token写入服务后再执行导航
            DeviceService.Token = token;
            // 强制重载页面,绕过Blazor路由缓存
            Navigation.NavigateTo("/Ninja", forceLoad: true);
        }
        catch (Exception ex)
        {
            // 跳转至错误页处理异常
            Navigation.NavigateTo($"/Error?message={Uri.EscapeDataString(ex.Message)}");
        }
    }
}

2. 避免/Ninja页面路由循环

在/Ninja页面初始化时,需添加状态标记防止重复触发跳转,同时检查Token有效性而非仅判断是否为空:

@page "/Ninja"
@inject NavigationManager Navigation
@inject DeviceService DeviceService
@inject OAuthService OAuthService

@code {
    private bool _isRedirecting = false;

    protected override async Task OnInitializedAsync()
    {
        if (_isRedirecting) return;

        var token = DeviceService.Token;
        // 检查Token是否存在且未过期
        if (string.IsNullOrEmpty(token) || await OAuthService.IsTokenExpiredAsync(token))
        {
            _isRedirecting = true;
            var authUrl = OAuthService.GenerateAuthorizationUrl();
            Navigation.NavigateTo(authUrl, forceLoad: true);
        }
        else
        {
            // 执行API调用逻辑
            await LoadAuthorizedData();
        }
    }

    private async Task LoadAuthorizedData()
    {
        var data = await ApiService.GetProtectedDataAsync(DeviceService.Token);
        // 处理返回数据
    }
}

3. 确保Token存储线程安全

DeviceService需保证Token读写的线程安全性,避免Callback页面写入Token后,/Ninja页面读取到旧值:

public class DeviceService
{
    private string _token;
    private readonly object _lockObj = new object();

    public string Token
    {
        get
        {
            lock (_lockObj)
            {
                return _token;
            }
        }
        set
        {
            lock (_lockObj)
            {
                _token = value;
            }
        }
    }
}

4. 额外异常处理措施

若仍出现NavigationException,可将导航操作包裹在InvokeAsync中,确保在Blazor同步上下文执行:

await InvokeAsync(() =>
{
    Navigation.NavigateTo("/Ninja", forceLoad: true);
});

同时确认OAuth提供商的回调URL与Blazor应用的/Callback页面完全一致(含HTTP/HTTPS、域名、端口),避免授权码无效导致的间接导航失败。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 10:43:23