【问题标题】:Storing a JWT token in Blazor Client Side在 Blazor 客户端中存储 JWT 令牌
【发布时间】:2020-12-21 04:26:19
【问题描述】:

我正在尝试我的第一个 Blazor 应用程序,客户端,并且正在与身份验证作斗争。我已经设法调用我的 API、获取令牌并在应用程序中进行身份验证。我需要将 JWT 令牌存储在某处——我认为,在声明中,可能没问题。 (也许这就是我出错的地方,它应该以某种方式出现在 LocalStorage 或其他地方?)

因此,对于我的授权,我有一个 AuthenticationStateProvider,其中 - 一切正常。我得到认证。但我无法访问我的令牌。

这是添加它的正确位置吗?如果是这样,为什么这段代码让我失败了?

    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??
         
        }
    }

我的索引页面正在工作:

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

按预期登录时,它会显示我的名字。

但是在我需要将 JWT 令牌发送到 API 的页面上,我试图找到它:


        var user = authState.User;

但user 似乎没有'token'参数。

我应该如何存储我的 JWT,并在我即将使用我的 http 客户端时访问它?

【问题讨论】:

  • 为什么不使用 Identity Cookie 身份验证?将访问令牌存储在 localStorage 或 sessionStorage (js) 中可以使您在网页中包含的每个 javascript 文件都可以访问该令牌

标签: c# asp.net-core blazor


【解决方案1】:

您将令牌保存在 Web 浏览器的本地存储中。像这样的

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);
        }
    }
}

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

【讨论】:

  • 令牌应存储在会话 IMO 中
  • @aguafrommars 不是每次我们关闭并重新打开浏览器时都会重新初始化会话吗?似乎每次都必须重新连接会破坏用户体验
  • @pascx64 如果会话 cookie 仍然有效,用户在关闭浏览器后不必重新连接,SSO 应该仍然有效。 OAuth 令牌由默认 Blazor OAuth 处理程序存储在会话存储中
【解决方案2】:

我建议你使用 Blazored 库。它们提供本地和会话存储选项。我使用后者。 https://github.com/Blazored/SessionStorage的信息

【讨论】:

    【解决方案3】:

    如果您依赖 Msal 进行身份验证,例如将其与 Azure B2C 一起使用,则以下答案是相关的:

    builder.Services.AddMsalAuthentication(options =>
    {
        ...
        options.ProviderOptions.Cache.CacheLocation = "localStorage";
    });
    

    【讨论】:

      猜你喜欢
      • 2019-10-02
      • 2020-03-23
      • 2021-02-27
      • 2021-08-12
      • 2021-02-03
      • 2022-06-11
      • 1970-01-01
      • 2020-01-31
      • 2015-09-20
      相关资源
      最近更新 更多