Blazor 登录页面 jwt 不记名令牌和授权

问题描述 投票:0回答:1
 @page "/login"
@using System.Net.Http
@using System.Net.Http.Json
@using System.Text.Json
@inject IHttpClientFactory HttpClientFactory
@inject IJSRuntime JSRuntime

<h3>Login</h3>

@if (!string.IsNullOrWhiteSpace(errorMessage))
{
  <div class="alert alert-danger">@errorMessage</div>
}

<div class="form-group">
  <label for="email">Email:</label>
  <input type="email" class="form-control" id="email" @bind="email" />
</div>
<div class="form-group">
  <label for="password">Password:</label>
  <input type="password" class="form-control" id="password" @bind="password" />
</div>
<button class="btn btn-primary" @onclick="Login">Login</button>

@code {
  private string email;
  private string password;
  private string errorMessage;

  private async Task Login()
  {
      try
      {
          var httpClient = HttpClientFactory.CreateClient();

          // Create a JSON object to send to the API
          var loginData = new
          {
              Email = email,
              Password = password
          };

          // Serialize the object to JSON
          var jsonContent = new StringContent(JsonSerializer.Serialize(loginData), Encoding.UTF8, "application/json");

          // Send a POST request to your authentication API to get a JWT token
          var response = await httpClient.PostAsJsonAsync("https://your-auth-api.com/login", loginData);

          // Check if the request was successful
          if (response.IsSuccessStatusCode)
          {
              // Deserialize the response to get the JWT token
              var token = await response.Content.ReadAsStringAsync();

              // Store the token securely (e.g., in local storage or a secure cookie)
              // For demonstration, we'll just set it in a session variable
              await JSRuntime.InvokeVoidAsync("sessionStorage.setItem", "jwtToken", token);

              // Redirect to the secured page
              NavigationManager.NavigateTo("/secure");
          }
          else
          {
              errorMessage = "Invalid email or password.";
          }
      }
      catch (Exception ex)
      {
          errorMessage = "An error occurred: " + ex.Message;
      }
  }
}

我正在尝试向 api 发送登录信息,并获取一个在每个页面中使用的令牌,以便再次发送到 api,但我是 blazor 的新手,所以我如何使用 jwt 持有者获取令牌并将其发送到其他页面, 另外,如果有人检查我的代码并给我反馈(无论其真实与否),我都会很高兴。非常感谢

jwt blazor authorization blazor-webassembly bearer-token
1个回答
0
投票

您需要开始的所有内容都在这个存储库中。这是我的第一次介绍,它让我很快就开始了。 https://github.com/cornflourblue/blazor-web assembly-jwt-authentication-example

文档和演示在此页面中。 https://jasonwatmore.com/post/2020/08/13/blazor-web assembly-jwt-authentication-example-tutorial

从存储库检查此类 “AuthenticationService.cs”

using BlazorApp.Models;
using Microsoft.AspNetCore.Components;
using System.Threading.Tasks;

namespace BlazorApp.Services
{
    public interface IAuthenticationService
    {
        User User { get; }
        Task Initialize();
        Task Login(string username, string password);
        Task Logout();
    }

    public class AuthenticationService : IAuthenticationService
    {
        private IHttpService _httpService;
        private NavigationManager _navigationManager;
        private ILocalStorageService _localStorageService;

        public User User { get; private set; }

        public AuthenticationService(
            IHttpService httpService,
            NavigationManager navigationManager,
            ILocalStorageService localStorageService
        ) {
            _httpService = httpService;
            _navigationManager = navigationManager;
            _localStorageService = localStorageService;
        }

        public async Task Initialize()
        {
            User = await _localStorageService.GetItem<User>("user");
        }

        public async Task Login(string username, string password)
        {
            User = await _httpService.Post<User>("/users/authenticate", new { username, password });
            await _localStorageService.SetItem("user", User);
        }

        public async Task Logout()
        {
            User = null;
            await _localStorageService.RemoveItem("user");
            _navigationManager.NavigateTo("login");
        }
    }
}

然后,一旦您登录,您就可以通过这种方式调用您的后端。

namespace BlazorApp.Services
{
    public interface IHttpService
    {
        Task<T> Get<T>(string uri);
        Task<T> Post<T>(string uri, object value);
    }

    public class HttpService : IHttpService
    {
        private HttpClient _httpClient;
        private NavigationManager _navigationManager;
        private ILocalStorageService _localStorageService;
        private IConfiguration _configuration;

        public HttpService(
            HttpClient httpClient,
            NavigationManager navigationManager,
            ILocalStorageService localStorageService,
            IConfiguration configuration
        ) {
            _httpClient = httpClient;
            _navigationManager = navigationManager;
            _localStorageService = localStorageService;
            _configuration = configuration;
        }

        public async Task<T> Get<T>(string uri)
        {
            var request = new HttpRequestMessage(HttpMethod.Get, uri);
            return await sendRequest<T>(request);
        }

        public async Task<T> Post<T>(string uri, object value)
        {
            var request = new HttpRequestMessage(HttpMethod.Post, uri);
            request.Content = new StringContent(JsonSerializer.Serialize(value), Encoding.UTF8, "application/json");
            return await sendRequest<T>(request);
        }

        // helper methods

        private async Task<T> sendRequest<T>(HttpRequestMessage request)
        {
            // add jwt auth header if user is logged in and request is to the api url
            var user = await _localStorageService.GetItem<User>("user");
            var isApiUrl = !request.RequestUri.IsAbsoluteUri;
            if (user != null && isApiUrl)
                request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", user.Token);

            using var response = await _httpClient.SendAsync(request);

            // auto logout on 401 response
            if (response.StatusCode == HttpStatusCode.Unauthorized)
            {
                _navigationManager.NavigateTo("logout");
                return default;
            }

            // throw exception on error response
            if (!response.IsSuccessStatusCode)
            {
                var error = await response.Content.ReadFromJsonAsync<Dictionary<string, string>>();
                throw new Exception(error["message"]);
            }

            return await response.Content.ReadFromJsonAsync<T>();
        }
    }
}

祝一切顺利,继续编码。

© www.soinside.com 2019 - 2024. All rights reserved.