I trying to implement token base authentication in Blazor webassembly web application with Prerendering enabled.
The steps I have done so far:
- Created a sample Blazor Webassembly application
- Followed the Official MS doc: Prerender and integrate ASP.NET Core Razor components
- Checked if application works
- Added token base authentication (custom) changes - ref.
It gives an error at AuthStateProvider
public class AuthStateProvider : AuthenticationStateProvider
{
public override async Task<AuthenticationState> GetAuthenticationStateAsync()
{
var token = await _localStorage.GetItemAsync<string>("authToken");
if (string.IsNullOrWhiteSpace(token))
return _anonymous;
_httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("bearer", token);
return new AuthenticationState(new ClaimsPrincipal(new ClaimsIdentity(JwtParser.ParseClaimsFromJwt(token), "jwtAuthType")));
return _anonymous;
}
}
It gives an error
InvalidOperationException: JavaScript interop calls cannot be issued during server-side prerendering, because the page has not yet loaded in the browser. Prerendered components must wrap any JavaScript interop calls in conditional logic to ensure those interop calls are not attempted during prerendering.
at this line
var token = await _localStorage.GetItemAsync<string>("authToken");
Now that is obvious; this line should be wrapped in a condition to check for prerendering like:
public class AuthStateProvider : AuthenticationStateProvider
{
public override async Task<AuthenticationState> GetAuthenticationStateAsync()
{
var isNotPreRendering = this._httpContextAccessor.HttpContext.Response.HasStarted;
if(isNotPreRendering)
{
var token = await _localStorage.GetItemAsync<string>("authToken");
if (string.IsNullOrWhiteSpace(token))
return _anonymous;
_httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("bearer", token);
return new AuthenticationState(new ClaimsPrincipal(new ClaimsIdentity(JwtParser.ParseClaimsFromJwt(token), "jwtAuthType")));
}
return _anonymous;
}
}
But the value of isNotPreRendering always false. Is there any other way or work around to make it work?
IHttpContextAccessorshould not be used with Blazor. I suggest you read about this matter. Github issue, DocOnAfterRenderAsync()for example.OnAfterRenderAsync()but not sure how to do itAuthStateProvider.GetAuthenticationStateAsynccalled ?