I managed to achieve what I want but I consider this a workaround more than a robust solution. This seems like a known issue.
Firstly, I updated the code at App.razor to the following
private IComponentRenderMode? RenderModeForPage => new InteractiveServerRenderMode(prerender: false);
Now, the login page will keep reloading indefinitely, so I updated the AccountLayout.razor like this in order to control the continuous reload
@if (HttpContext is null && !IsInteractive)
{
<p>@localizer["Loading"]</p>
}
else
{
@Body
}
@code {
[CascadingParameter] private HttpContext? HttpContext { get; set; }
private bool IsInteractive
{
get
{
return NavigationManager.Uri.Contains("interactive=true") || NavigationManager.Uri.Contains("interactive%3Dtrue");
}
}
protected override void OnParametersSet()
{
if (HttpContext is null && !IsInteractive)
{
NavigationManager.NavigateTo($"{NavigationManager.Uri}?interactive=true", forceLoad: true);
}
}
}
Nothing fancy here, just adding a query string to stop the reload.
Now, I thought I should be able to access the protectedLocalStorage
after the successful login but I still find it equals null
at GetAuthenticationStateAsync()
So, I added a new razor component RedirectComponent.razor & redirected from login.razor to it, then redirect from the new component to the ReturnUrl
@page "/RedirectComponent"
@inject NavigationManager NavigationManager
@inject IStringLocalizer<Resource> localizer
<p>@localizer["Loading"]</p>
@code {
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender)
{
var uri = new Uri(NavigationManager.Uri);
var query = System.Web.HttpUtility.ParseQueryString(uri.Query);
var returnUrl = query["ReturnUrl"];
StateHasChanged();
NavigationManager.NavigateTo(returnUrl ?? "Account/Login", replace: true); //to prevent the page from registering in the browser history
}
}
}
This is login.razor code after successful login
var uri = new Uri(NavigationManager.Uri);
var query = System.Web.HttpUtility.ParseQueryString(uri.Query);
ReturnUrl = query["ReturnUrl"];
ReturnUrl = !string.IsNullOrEmpty(ReturnUrl) && ReturnUrl.Contains("?") ? ReturnUrl.Split("?")[0] : ReturnUrl;
StateHasChanged();
NavigationManager.NavigateTo("RedirectComponent?ReturnUrl=" + ReturnUrl ?? "", forceLoad: true);
Now, it's working as intended but I'm not satisfied with all these workarounds. I believe these should be a much more straightforward solution as this is a very common use case when using a third-party API to authenticate.