Niels Brinch
Niels Brinch

Reputation: 3612

Prevent code from running on my page when I stop it from my MainLayout

I have a Blazor PWA app with MainLayout and then a bunch of pages. Whenever the user is not logged in, I want to redirect them to the login screen.

It would be great if I could redirect them to the login screen from the MainLayout where I already know that the user is not logged in. I am simply checking a cookie value and then using NavigationManager.NavigateTo to move the user to a login page.

However, the initialization code on the individual pages is still running and fails because they assume that the user is logged in.

I can fix it by putting login validation code on every single page. However, I would really like to be able to just checking the login in one place and thereby simplifying all my pages.

So is there a way to do something like this:

if (!isLoggedIn)
{
    NavigationManager.NavigateTo($"/login");
    return;
    // Stop any other code from running until the navigation is complete
}

Or maybe some other solution to my general issue.

Upvotes: 2

Views: 1003

Answers (1)

Dimitris Maragkos
Dimitris Maragkos

Reputation: 11302

You can use AuthorizeRouteView component to achieve your requirement. Use it inside App.razor:

<Router AppAssembly="@typeof(Program).Assembly" PreferExactMatches="@true">
    <Found Context="routeData">
        <AuthorizeRouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)">
            <NotAuthorized>
                @if (!context.User.Identity.IsAuthenticated)
                {
                    <RedirectToLogin />
                }
                else
                {
                    <p>You are not authorized to access this resource.</p>
                }
            </NotAuthorized>
        </AuthorizeRouteView>
    </Found>
    <NotFound>
        <LayoutView Layout="@typeof(MainLayout)">
            <p>Sorry, there's nothing at this address.</p>
        </LayoutView>
    </NotFound>
</Router>

And create RedirectToLogin.razor:

@inject NavigationManager Navigation
@code {
    protected override void OnInitialized()
    {
        Navigation.NavigateTo($"/login");
    }
}

AuthorizeRouteView component displays an "Authorizing..." message while checking if the user is authorized and only if the check succeeds it loads the page.

enter image description here

You can customize what is displayed during the authorization check by defining the Authorizing template:

<AuthorizeRouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)">
    <Authorizing>
        @* E.g. show a spinner while authorizing *@
    </Authorizing>

    <NotAuthorized>
         ...       
    </NotAuthorized>
</AuthorizeRouteView>

More info about AuthorizeRouteView component: https://learn.microsoft.com/en-us/aspnet/core/blazor/security/?view=aspnetcore-6.0#customize-unauthorized-content-with-the-router-component

Upvotes: 3

Related Questions