JWT不会与Blazor一起存储在ASP.NET Core中

Jef*_*ito 6 c# jwt asp.net-core blazor

我按照本教程:https://medium.com/@st.mas29/microsoft-blazor-web-api-with-jwt-authentication-part-1-f33a44abab9d

我下载了这个例子:https://github.com/StuwiiDev/DotnetCoreJwtAuthentication/tree/Part2

我可以看到令牌已创建,但我不明白它是如何保存或应该保存在客户端,因为每次我访问它时SampleDataController,它都有Authorize标签,它返回401.

使用Postman调用和添加令牌时,它可以正常工作.

我对用户进行身份验证缺少什么?不Microsoft.AspNetCore.Authentication.JwtBearer处理客户端部分(存储令牌)?

itm*_*nus 9

我对用户进行身份验证缺少什么?Microsoft.AspNetCore.Authentication.JwtBearer不处理客户端部分(存储令牌)吗?

在JwtBearer服务器端运行时,它只会验证的要求,即授权头Authorization: Bearer your_access_token,并不会在意你如何WebAssembly代码运行.所以你需要用jwt accessToken发送请求.由于本教程建议你应该使用localStorage,让我们存储accessToken与localStorage.

因为WebAssembly还没有访问权限BOM,我们需要一些javascript代码作为粘合剂.要做到这一点,添加一个helper.js下JwtAuthentication.Client/wwwroot/js/:

var wasmHelper = {};

wasmHelper.ACCESS_TOKEN_KEY ="__access_token__";

wasmHelper.saveAccessToken = function (tokenStr) {
    localStorage.setItem(wasmHelper.ACCESS_TOKEN_KEY,tokenStr);
};

wasmHelper.getAccessToken = function () {
    return localStorage.getItem(wasmHelper.ACCESS_TOKEN_KEY);
};
Run Code Online (Sandbox Code Playgroud)

并参考你的脚本 JwtAuthentication.Client/wwwroot/index.html

<body>
    <app>Loading...</app>
    <script src="js/helper.js"></script>
    <script src="_framework/blazor.webassembly.js"></script>
</body>
Run Code Online (Sandbox Code Playgroud)

现在,让我们将javascript代码包装到C#中.创建一个新文件Client/Services/TokenService.cs:

public class TokenService
{
    public Task SaveAccessToken(string accessToken) {
        return JSRuntime.Current.InvokeAsync<object>("wasmHelper.saveAccessToken",accessToken);
    }
    public Task<string> GetAccessToken() {
        return JSRuntime.Current.InvokeAsync<string>("wasmHelper.getAccessToken");
    }
}
Run Code Online (Sandbox Code Playgroud)

现在,我们可以注入TokenService 到Login.cshtml,并用它来保存令牌:

// file: Startup.cs 
services.AddSingleton<TokenService>(myTokenService);
Run Code Online (Sandbox Code Playgroud)

假设您要在其中发送数据 FetchData.cshtml

@using JwtAuthentication.Client.Services
// ...
@page "/login"
// ...
@inject TokenService tokenService

// ...

@functions {
    public string Email { get; set; } = "";
    public string Password { get; set; } = "";
    public string Token { get; set; } = "";


    /// <summary>
    /// response from server
    /// </summary>
    private class TokenResponse{
        public string Token;
    }

    private async Task SubmitForm()
    {
        var vm = new TokenViewModel
        {
            Email = Email,
            Password = Password
        };

        var response = await Http.PostJsonAsync<TokenResponse>("http://localhost:57778/api/Token", vm);
        await tokenService.SaveAccessToken(response.Token);
    }
}
Run Code Online (Sandbox Code Playgroud)

结果将是:

在此输入图像描述

  • 感谢您提供了一个很棒的解释,现在它可以了!仅供记录:为了能够注入`TokenService`,我需要将它添加到服务中`Startup.ConfigureServices - services.AddSingleton <TokenService>(myTokenService);` (2认同)