Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Storing a JWT token in Blazor Client Side

I am trying my first Blazor app, client side, and am battling with authentication. I have managed to call my API, get a token, and authenticate in the app. I need to store the JWT token somewhere - and I thought, in the claims, might be OK. (Maybe this is where I go wrong, and it should be somehow, in LocalStorage or something?)

So for my authorisation, I have a AuthenticationStateProvider, where - things work OK. I get authenticated. But I am unable to acceess my token.

Is this the right place to be adding it? And if so, why is this code failing me?

    public class CustomAuthenticationStaterProvider : AuthenticationStateProvider
    {
        public override Task<AuthenticationState> GetAuthenticationStateAsync()
        {
            var identity = new ClaimsIdentity();

            var user = new ClaimsPrincipal(identity);

            return Task.FromResult(new AuthenticationState(user));
        }

        public void AuthenticateUser(AuthenticationResponse request)
        {
            if (request.ResponseDetails.IsSuccess == false)
                return;

            var identity = new ClaimsIdentity(new[]
            {
                new Claim("token", request.Token),
                new Claim(ClaimTypes.Email, request.Email),
                new Claim(ClaimTypes.Name, $"{request.Firstname} {request.Surname}"),
            }, "apiauth_type");

            var user = new ClaimsPrincipal(identity);

            NotifyAuthenticationStateChanged(Task.FromResult(new AuthenticationState(user)));
        }

        public void LogoutUser()
        {
            // Hwo??
         
        }
    }

My index page is working:

    <Authorized>
        <p>Welcome, @context.User.Identity.Name</p>
    </Authorized>
    <NotAuthorized>
        <p>You're not signed in</p>
    </NotAuthorized>
</AuthorizeView>

It shows my name, when logged in, as expected.

But on a page where I need to send the JWT token to the API, I am trying to find it:


        var user = authState.User;

But user seems to have no 'token' parameter.

enter image description here

How should I be storing my JWT, and having access to it when ever I am about to use my http client?

like image 510
Craig Avatar asked Jan 24 '23 18:01

Craig


1 Answers

You save token in local storage of web browser. something like this

using Microsoft.JSInterop;
using System.Text.Json;
using System.Threading.Tasks;

namespace BlazorApp.Services
{
    public interface ILocalStorageService
    {
        Task<T> GetItem<T>(string key);
        Task SetItem<T>(string key, T value);
        Task RemoveItem(string key);
    }

    public class LocalStorageService : ILocalStorageService
    {
        private IJSRuntime _jsRuntime;

        public LocalStorageService(IJSRuntime jsRuntime)
        {
            _jsRuntime = jsRuntime;
        }

        public async Task<T> GetItem<T>(string key)
        {
            var json = await _jsRuntime.InvokeAsync<string>("localStorage.getItem", key);

            if (json == null)
                return default;

            return JsonSerializer.Deserialize<T>(json);
        }

        public async Task SetItem<T>(string key, T value)
        {
            await _jsRuntime.InvokeVoidAsync("localStorage.setItem", key, JsonSerializer.Serialize(value));
        }

        public async Task RemoveItem(string key)
        {
            await _jsRuntime.InvokeVoidAsync("localStorage.removeItem", key);
        }
    }
}

source: https://jasonwatmore.com/post/2020/08/13/blazor-webassembly-jwt-authentication-example-tutorial

like image 98
Do Nhu Vy Avatar answered Feb 03 '23 18:02

Do Nhu Vy