Search code examples
blazorblazor-client-sideblazor-webassembly

Blazor WASM redirect to login when not authenticated - Don't show layout


I have a Blazor WASM having 2 layouts:

  1. MainLayout
  2. LoginLayout

My main Index file has an Authorized attribute

@page "/"
@using Microsoft.AspNetCore.Authorization
@using Microsoft.AspNetCore.Components.WebAssembly.Authentication
@attribute [Authorize]

When its not authorized is being redirected to "auth/login" which uses a different layout (LoginLayout) where I have a simple login page.

The problem im facing is that when I access the application I can see for a second the MainLayout (header, navigation left menu, footer) and then I see my blank screen with my login.

This means that because Index is the main route and uses MainLayout, it takes about 1 second to validate and do the redirect to my Login page and thats why the Layout issue.

Is there a way to do the redirect before the MainLayout is rendered in the page? Or a way to not show the Layout HTML if the user is not authenticated?


Solution

  • Try the following code... I tested it superficially in WebAssembly hosted with individual authentication and it seems fine. If the user is not authenticated, and the Index component is annotated with the Authorize attribute, he's redirected to the Login page, without seeing the MainLayout.

    Change the code in MainLayout.razor to the following:

    @inherits LayoutComponentBase
    
    <AuthorizeView>
        <Authorized>
            <div class="sidebar">
                <NavMenu />
            </div>
    
            <div class="main">
                <div class="top-row px-4 auth">
                    <LoginDisplay />
                    <a href="https://learn.microsoft.com/aspnet/" target="_blank">About</a>
                </div>
    
                <div class="content px-4">
                    @Body
                </div>
            </div>
    
        </Authorized>
        <NotAuthorized>
            <div class="main">
                <div class="content px-4">
                    @Body
                </div>
            </div>
       </NotAuthorized>
    </AuthorizeView> 
    

    Test the code above, and see if it does satisfy your expectations, then model you things accordingly. Note that your Login component should be decorated with the @layout directive, so that Blazor will display the Login component within your custom layout.

    Model your custom layout after the DEFAULT MainLayout...Remove the unnecessary parts, and add your own as needed.

    This: @inherits LayoutComponentBase

    And this:

       <div class="main">
                    <div class="content px-4">
                        @Body
                    </div>
       </div> 
    

    are a must...