fix switch club:
Problem: RefreshSignInAsync in UserService.SwitchClubAsync (Zeile 719) setzte zwar den neuen Cookie, aber HttpClient.PostAsJsonAsync empfing diesen Cookie nur intern - der Browser bekam ihn nie.
Lösung: Form-POST statt HttpClient-API-Call, wie bei Login/Logout.
Änderungen:
1. ClubSwitcher.razor - Komplett überarbeitet:
- HttpClient durch natives <form method="post"> ersetzt
- AntiForgery-Token manuell gesetzt (wie LogoutButton)
- Kein JavaScript/Client-Code mehr nötig
2. AuthController.cs (Zeile 146):
- [FromBody] → [FromForm]
- [ValidateAntiForgeryToken] aktiviert
Ablauf jetzt:
1. User klickt auf Club im Dropdown
2. Form-POST an /auth/switch-club
3. Controller ruft SwitchClubAsync → DB-Update + RefreshSignInAsync
4. LocalRedirect("/dashboard") → Browser erhält neuen Cookie direkt
5. Claims sind beim Reload korrekt
This commit is contained in:
parent
3b65f9f1cd
commit
39d4629e72
|
|
@ -1,16 +1,10 @@
|
|||
@using System.Net
|
||||
@using Fluxor
|
||||
@using Koogle.Application.DTOs
|
||||
@using Koogle.Web.Store.AuthState
|
||||
@using Koogle.Application.Interfaces
|
||||
@using Microsoft.AspNetCore.Antiforgery
|
||||
|
||||
@inject IState<AuthState> AuthState
|
||||
@inject NavigationManager NavigationManager
|
||||
@inject IUserService UserService
|
||||
@inject HttpClient HttpClient;
|
||||
@inject Microsoft.AspNetCore.Antiforgery.IAntiforgery Antiforgery
|
||||
@inject IAntiforgery Antiforgery
|
||||
@inject IHttpContextAccessor HttpContextAccessor
|
||||
@inject IDispatcher Dispatcher
|
||||
|
||||
@inherits Fluxor.Blazor.Web.Components.FluxorComponent
|
||||
|
||||
|
|
@ -27,14 +21,24 @@
|
|||
<ChildContent>
|
||||
@foreach (var club in AuthState.Value.AvailableClubs)
|
||||
{
|
||||
<MudMenuItem OnClick="@(() => SwitchClubAsync(club.ClubId))"
|
||||
Disabled="@(club.ClubId == AuthState.Value.CurrentClub?.ClubId)">
|
||||
@if (club.ClubId == AuthState.Value.CurrentClub?.ClubId)
|
||||
{
|
||||
@if (club.ClubId == AuthState.Value.CurrentClub?.ClubId)
|
||||
{
|
||||
<MudMenuItem Disabled="true">
|
||||
<MudIcon Icon="@Icons.Material.Filled.Check" Size="Size.Small" Class="mr-2"/>
|
||||
}
|
||||
@club.ClubName
|
||||
</MudMenuItem>
|
||||
@club.ClubName
|
||||
</MudMenuItem>
|
||||
}
|
||||
else
|
||||
{
|
||||
<form method="post" action="/auth/switch-club">
|
||||
<input type="hidden" name="__RequestVerificationToken" value="@_token" />
|
||||
<input type="hidden" name="clubId" value="@club.ClubId" />
|
||||
<input type="hidden" name="userProfileId" value="@AuthState.Value.CurrentUser?.ProfileId" />
|
||||
<button type="submit" class="mud-menu-item mud-ripple" style="width:100%; text-align:left; background:none; border:none; cursor:pointer;">
|
||||
@club.ClubName
|
||||
</button>
|
||||
</form>
|
||||
}
|
||||
}
|
||||
</ChildContent>
|
||||
</MudMenu>
|
||||
|
|
@ -53,64 +57,17 @@ else if (AuthState.Value.IsAuthenticated && AuthState.Value.HasNoClub)
|
|||
}
|
||||
|
||||
@code {
|
||||
private string _antiToken;
|
||||
private string _token = string.Empty;
|
||||
|
||||
protected override void OnAfterRender(bool firstRender)
|
||||
protected override void OnInitialized()
|
||||
{
|
||||
if (firstRender)
|
||||
base.OnInitialized();
|
||||
|
||||
var http = HttpContextAccessor.HttpContext;
|
||||
if (http != null)
|
||||
{
|
||||
var http = HttpContextAccessor.HttpContext!;
|
||||
var tokens = Antiforgery.GetAndStoreTokens(http);
|
||||
_antiToken = tokens.RequestToken!;
|
||||
_token = tokens?.RequestToken ?? string.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
private async Task SwitchClubAsync(Guid clubId)
|
||||
{
|
||||
if (AuthState.Value.CurrentUser == null)
|
||||
return;
|
||||
|
||||
var model = new SwitchClubFormDto()
|
||||
{
|
||||
ClubId = clubId,
|
||||
UserProfileId = AuthState.Value.CurrentUser.ProfileId
|
||||
};
|
||||
|
||||
try
|
||||
{
|
||||
HttpClient.DefaultRequestHeaders.Remove("RequestVerificationToken");
|
||||
HttpClient.DefaultRequestHeaders.Add(
|
||||
"RequestVerificationToken",
|
||||
_antiToken
|
||||
);
|
||||
|
||||
var basepath = NavigationManager.BaseUri;
|
||||
var url = $"{basepath}auth/switch-club";
|
||||
await HttpClient.PostAsJsonAsync(url, model);
|
||||
|
||||
// Dispatcher.Dispatch(new AuthState.InitializeAuthSuccessAction(model.UserProfileId, model.ClubId, roles));
|
||||
|
||||
|
||||
NavigationManager.NavigateTo("/dashboard", forceLoad: true);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Console.WriteLine(e);
|
||||
throw;
|
||||
}
|
||||
|
||||
// try
|
||||
// {
|
||||
// var success = await UserService.SwitchClubAsync(AuthState.Value.CurrentUser.ProfileId, clubId);
|
||||
// if (success)
|
||||
// {
|
||||
// // Force page reload to refresh claims
|
||||
// NavigationManager.NavigateTo(NavigationManager.Uri, forceLoad: true);
|
||||
// }
|
||||
// }
|
||||
// catch (Exception ex)
|
||||
// {
|
||||
// Console.WriteLine($"Club switch failed: {ex.Message}");
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -142,11 +142,11 @@ namespace Koogle.Web.Controllers
|
|||
/// Handles switch club.
|
||||
/// </summary>
|
||||
[HttpPost("switch-club")]
|
||||
//[ValidateAntiForgeryToken]
|
||||
public async Task<IActionResult> SwitchClub([FromBody] SwitchClubFormDto input)
|
||||
[ValidateAntiForgeryToken]
|
||||
public async Task<IActionResult> SwitchClub([FromForm] SwitchClubFormDto input)
|
||||
{
|
||||
await _userService.SwitchClubAsync(input.UserProfileId, input.ClubId);
|
||||
return LocalRedirect($"/dashboard");
|
||||
return LocalRedirect("/dashboard");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue