Files
Atomx/Atomx.Admin/Atomx.Admin.Client/Pages/Logout.razor
2025-12-04 19:07:04 +08:00

76 lines
3.0 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
@page "/logout"
@layout EmptyLayout
@inject IJSRuntime JS
@inject ILogger<Logout> Logger
@inject NavigationManager Navigation
@inject AuthenticationStateProvider AuthStateProvider
@inject HttpService HttpService
@using System.Text.Json
@code {
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (!firstRender) return;
try
{
// 如果运行在浏览器 (WASM),直接调用后端 API 并清除 localStorage / provider
if (OperatingSystem.IsBrowser())
{
Logger.LogInformation("WASM logout: call API and clear local storage");
try
{
await HttpService.Post<ApiResult<string>>("/api/sign/out", null);
}
catch { /* 忽略网络错误,仍继续清理客户端状态 */ }
if (AuthStateProvider is Atomx.Admin.Client.Utils.PersistentAuthenticationStateProvider provider)
{
await provider.MarkUserAsLoggedOut();
}
Navigation.NavigateTo("/account/login");
}
else
{
// Server 模式:通过浏览器 fetch 发起带凭据的请求以便浏览器接收并删除 Cookie然后强制重载
Logger.LogInformation("Server logout: use browser fetch to call /api/sign/out");
var jsResult = await JS.InvokeAsync<JsonElement>("__atomx_post_json", "/api/sign/out", (object?)null);
// 尝试解析返回,忽略细节
var success = jsResult.ValueKind == JsonValueKind.Object && jsResult.TryGetProperty("success", out var sp) && sp.GetBoolean();
Logger.LogInformation("Server logout result: {Success}", success);
// 尽管我们可能已经处理了服务器态,强制重新加载确保 Circuit 更新
Navigation.NavigateTo("/account/login", forceLoad: true);
}
}
catch (Exception ex)
{
Logger.LogWarning(ex, "Logout failed but proceeding to login page");
Navigation.NavigateTo("/account/login", forceLoad: true);
}
}
}
@* 页面内 JS 辅助:用于在 Server 模式下从浏览器发起 POST 并携带凭证,使浏览器接收 Set-Cookie/删除 Cookie *@
<script>
window.__atomx_post_json = async function (url, data) {
try {
const res = await fetch(url, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
credentials: 'include',
body: data ? JSON.stringify(data) : null
});
const text = await res.text();
try {
return JSON.parse(text);
} catch {
return { success: res.ok, message: text };
}
} catch (err) {
return { success: false, message: err?.toString() ?? 'network error' };
}
};
</script>