學習ASP.NET Core Blazor編程系列二十六——登錄(5)

来源:https://www.cnblogs.com/chillsrc/archive/2023/02/19/17135448.html
-Advertisement-
Play Games

Dapper 是一個 容易上手,輕量級,靈活高效,開源的 迷你 ORM,由 Stack Overflow 團隊的 Sam Saffron 出品,你可以利用 Dapper 簡化數據訪問並且支持高性能, 還有一點, Dapper 提供了很多非同步方法,本篇我們就來聊一聊如何在 ASP.NET Core 中 ...


學習ASP.NET Core Blazor編程系列文章之目錄 學習ASP.NET Core Blazor編程系列一——綜述 學習ASP.NET Core Blazor編程系列二——第一個Blazor應用程式(上)
學習ASP.NET Core Blazor編程系列三——實體 學習ASP.NET Core Blazor編程系列五——列表頁面 學習ASP.NET Core Blazor編程系列七——新增圖書 學習ASP.NET Core Blazor編程系列八——數據校驗 學習ASP.NET Core Blazor編程系列十三——路由(完) 學習ASP.NET Core Blazor編程系列十五——查詢 學習ASP.NET Core Blazor編程系列十六——排序 學習ASP.NET Core Blazor編程系列二十——文件上傳(完) 學習ASP.NET Core Blazor編程系列二十一——數據刷新  學習ASP.NET Core Blazor編程系列二十二——登錄(1)  

九、模擬登錄

     登錄的本質原理同網頁應用是一樣的,一般的流程是:

      用戶打開登頁--》輸入賬號密碼後提交表單--》服務端驗證成功後生成cookie信息寫入瀏覽器--》之後用戶訪問頁面時瀏覽器會帶上此cookie信息作為用戶標識--》服務端解析此cookie信息就能識別這個用戶了。

      在webapi出現之後,出現了JWT這樣的認證方式,原理大同小異,相同的是, 認證信息都是保存在請求頭中傳遞的,不同是JWT中的認證信息需要編碼寫入請求頭之後再發送請求,不像瀏覽器,發送請求時會自動帶上cookie信息,不需要編碼。

Blazor中的登錄流程可以分成幾下幾個步驟:

  1. 啟用驗證
  2. 製作自定義AuthenticationStateProvider
  3. 修改App.razor
  4. 使用AuthorizeView和進行登錄驗證和角色授權

自定義AuthenticationStateProvider

       首先來理解一下什麼是AuthenticationStateProvider。AuthenticationStateProvider是一個抽象類,由Microsoft.AspNetCore.Components.Authorization類庫提供,主要用來提供當前用戶的認證狀態信息。既然是抽象類,我們需要自定義一個它的子類,由於是模擬登錄,進行登錄流程的驗證,因此我們先來做一個測試的Provider來試試。

1. 在Visual Studio 2022的解決方案資源管理器中,在項目名稱“BlazorAppDemo”上單擊滑鼠右鍵,在彈出菜單中選擇“添加—>新建文件夾”,並將之命名為“Auth”。如下圖。

 

2. 在Visual Studio 2022的解決方案資源管理器中,滑鼠左鍵選中“Auth”文件夾,右鍵單擊,在彈出菜單中選擇“添加—>類”,並將類命名為“ImitateAuthStateProvider”。 AuthStateProvider類的最核心方法是 Task<AuthenticationState> GetAuthenticationStateAsync()。基於最簡單的登錄機制,我們的擴展提供程式如下。具體代碼如下:

using BlazorAppDemo.Models;
using Microsoft.AspNetCore.Components.Authorization;
using System.Security.Claims;
 
namespace BlazorAppDemo.Auth
{
    public class ImitateAuthStateProvider : AuthenticationStateProvider
    {
        bool isLogin = false;
        public override Task<AuthenticationState> GetAuthenticationStateAsync()
        {
            if (isLogin)
            {
 
 
                var claims = new List<Claim>()
            {
                new Claim(ClaimTypes.Name,"user"),
                new Claim(ClaimTypes.Role, "admin")
            };
 
                var anonymous = new ClaimsIdentity(claims, "testAuthType");
                return Task.FromResult(new AuthenticationState(new ClaimsPrincipal(anonymous)));
            }
            else
            {

            var anonymous = new ClaimsIdentity();
            return Task.FromResult(new AuthenticationState(new ClaimsPrincipal(anonymous)));

        }
        }
        public void Login(UserInfo request)
        {
            if (request.UserName == "user" && request.Password == "111111")
                isLogin = true;    
            NotifyAuthenticationStateChanged(GetAuthenticationStateAsync());
           
       
        }

    }

}
ImitateAuthStateProvider繼承AuthenticationStateProvider,並重寫GetAuthenticationStateAsync方法。
  • var anonymous = new ClaimsIdentity();:我們現在進行模擬登錄,先做一個匿名的使用者,所以ClaimsIdentity的構造方法中不傳參數。
  • 返回AuthenticationState。
  • 我們給ClaimsIdentity一個List<Claim>屬性,其中有使用者的名字和角色,表示我們已登錄成功。

3. 在Visual Studio 2022的解決方案資源管理器中,使用滑鼠雙擊在文本編輯器中打開Program.cs文件,使用

builder.Services.AddScoped<ImitateAuthStateProvider>();
builder.Services.AddScoped<AuthenticationStateProvider>(implementationFactory =>
implementationFactory.GetRequiredService<ImitateAuthStateProvider>());

;這二行代碼使用DI方式註入ImitateAuthStateProvider。具體代碼如下:

 

using BlazorAppDemo.Data;
using BlazorAppDemo.Models;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Web;
using Microsoft.Extensions.Configuration;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Hosting;
using Microsoft.AspNetCore.Components.Authorization;
using BlazorAppDemo.Auth;

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.

builder.Services.AddRazorPages();

builder.Services.AddServerSideBlazor();

builder.Services.AddSingleton<WeatherForecastService>();

System.Console.WriteLine(ConfigHelper.Configuration["ConnectionStrings:BookContext"]);
builder.Services.AddDbContextFactory<BookContext>(opt =>
    opt.UseSqlServer(ConfigHelper.Configuration["ConnectionStrings:BookContext"]));
//builder.Services.AddScoped<AuthenticationStateProvider, ImitateAuthStateProvider>();
builder.Services.AddScoped<ImitateAuthStateProvider>();
builder.Services.AddScoped<AuthenticationStateProvider>(implementationFactory =>
implementationFactory.GetRequiredService<ImitateAuthStateProvider>());
 
 
var app = builder.Build();
 
// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Error");

    // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
    app.UseHsts();
}
 
 
using (var scope = app.Services.CreateScope())
{
    var services = scope.ServiceProvider;
    try
    {
        Console.WriteLine("資料庫開始初始化。");
        var context = services.GetRequiredService<BookContext>();

        // requires using Microsoft.EntityFrameworkCore;
        context.Database.Migrate();
        // Requires using RazorPagesMovie.Models;
        SeedData.Initialize(services);
        Console.WriteLine("資料庫初始化結束。");
    }
 
    catch (Exception ex)
    {
        var logger = services.GetRequiredService<ILogger<Program>>();

        logger.LogError(ex, "資料庫數據初始化錯誤.");

    }
}

 
app.UseHttpsRedirection();

app.UseStaticFiles();

app.UseRouting();

 
app.MapBlazorHub();

app.MapFallbackToPage("/_Host");

app.Run();

 

修改App.razor

現在我們已經完成了登錄認證的Provider了,接下來要做的事情,就是讓我們的頁面上的組件,可以獲取登錄信息,來決定是登錄用戶是否已經授權。這一步請參數之前的文章學習ASP.NET Core Blazor編程系列二十三——登錄(3)之中的“七、修改路由與啟動頁面”。

修改Login.razor頁面進行登錄

在Visual Studio 2022的文本編輯器中打開Login.razor組件文件,我們將滑鼠定位到@code中的SubmitHandler方法 ,寫上我們登錄成功的代碼。具體代碼如下:  

@page "/Login"
@using BlazorAppDemo.Auth;
@using BlazorAppDemo.Models
@using BlazorAppDemo.Utils
@layout LoginLayout
@inject NavigationManager NavigationManager
@inject ImitateAuthStateProvider AuthStateProvider;
 
<div class="card align-items-center">
    <div class="card-body my-2">
        <h3>Login</h3>
        <hr />
        <EditForm  Model="loginModel" OnValidSubmit="SubmitHandler" OnInvalidSubmit="InvalidHandler">
            <DataAnnotationsValidator />
           
            <div class="form-group">
                <label for="userName">  @HtmlHelper.GetDisplayName(loginModel ,m=> m.UserName)</label>
                <InputText @bind-Value="loginModel.UserName" class="form-control" id="userName" />
                <ValidationMessage For="()=>loginModel.UserName" />

            </div>
            <div class="form-group">
                <label for="pwd"> @HtmlHelper.GetDisplayName(loginModel ,m=> m.Password)</label>
                <InputPassword @bind-Value="loginModel.Password" class="form-control" id="pwd" />
                <ValidationMessage For="()=>loginModel.Password" />
            </div>

            <span class="form-control-plaintext"></span>
            <div class="form-group row">
                <div class="col-sm-10">
            <button class="btn btn-primary">登錄</button>
                </div>
            </div>
        </EditForm>

    </div>
</div>

 
@code {
    private UserInfo loginModel = new UserInfo();
    bool isAuthLoading = false;
    private void SubmitHandler()
    {
        Console.WriteLine($"用戶名:{loginModel.UserName} ,密碼:{loginModel.Password}");
         isAuthLoading = true;
    try {
         AuthStateProvider.Login(new UserInfo() {
                    UserName = loginModel.UserName,
                    Password =loginModel.Password
        });
            NavigationManager.NavigateTo("/Index");
    } catch (Exception ex) {

         Console.WriteLine(ex.Message);

    } finally {
        isAuthLoading = false;
    }
    }
 
    private void InvalidHandler()
    {

        Console.WriteLine($"用戶名: {loginModel.UserName} ,密碼:{loginModel.Password}");

    }

}
 

登錄並顯示當前用戶

1.在Visual Studio 2022的文本編輯器中打開MainLayout.razor組件文件,在AuthorizeView中顯示當前登錄用戶,具體代碼如下:

2.在Visual Studio 2022的菜單欄上,找到“調試-->開始調試”或是按F5鍵,Visual Studio 2022會生成BlazorAppDemo應用程式,瀏覽器中會Login登錄頁面。
@using BlazorAppDemo.Pages
@inherits LayoutComponentBase
 
<PageTitle>BlazorAppDemo</PageTitle>
 
<div class="page">
    <div class="sidebar">
        <NavMenu />
    </div>
 
    <main>
        <AuthorizeView>
            <Authorized>
              <div class="top-row px-4">
            <a href="https://docs.microsoft.com/aspnet/" target="_blank">About</a>
            <p>
       你好, @context.User.Identity.Name!
      </p>
 
        </div> 

        <article class="content px-4">
                    @Body
        </article>
            </Authorized>
            <NotAuthorized>
                <div style="margin: 120px 0; width:100%; text-align: center; color: red;">

                    <span style="font-size:20px">檢測到登錄超時,請重新<a href="/login" style="text-decoration:underline">登錄</a>

</span> </div> <RedirectToLogin></RedirectToLogin> </NotAuthorized> </AuthorizeView> </main> </div> 

3.我們在用戶名輸入框中輸入用戶名,在密碼輸入框中輸入密碼,點擊“登錄”按鈕,進行模擬登錄。我們進入了系統。如下圖。

 

     到此為止,我們已經實現了Blazor的登錄認證流程,接下來我們要來實現通過jwt進行登錄。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • IDEA如何使用Maven不通過模板創建javaWeb項目 1.創建項目 進入IDEA,點擊“項目”>“新建項目”,填寫項目信息,最後點擊“創建”。 點擊“創建”後,自動進入新創建的項目。 2.給項目配置Web框架 點擊 “文件”>“項目結構”,自動跳轉到項目結構。 點擊 “模塊” > “+” > ...
  • 給大家推薦一個比Redis性能更強的數據:KeyDB KeyDB是Redis的高性能分支,側重於多線程、記憶體效率和高吞吐量。除了性能改進外,KeyDB還提供主動複製、快閃記憶體和子密鑰過期等功能。KeyDB具有MVCC架構,允許您在不阻塞資料庫和降低性能的情況下執行密鑰和掃描等查詢。 KeyDB與Redi ...
  • ​ 函數的調用、定義、參數 ​編輯 #######命名關鍵字參數沒完 abs()函數:絕對值 >>> abs(100) 100 >>> abs(-20) 20 max()函數:接收任意多個參數,並返回最大的那個 >>> max(1, 2) 2 >>> max(2, 3, 1, -5) 3 數據類型轉 ...
  • 介紹 棧(stack)又名堆棧,它是一種運算受限的線性表。限定僅在表尾進行插入和刪除操作的線性表。這一端被稱為棧頂,相對地,把另一端稱為棧底。向一個棧插入新元素又稱作進棧、入棧或壓棧,它是把新元素放到棧頂元素的上面,使之成為新的棧頂元素;從一個棧刪除元素又稱作出棧或退棧,它是把棧頂元素刪除掉,使其相 ...
  • leetcode《圖解數據結構》劍指 Offer 34. 二叉樹中和為某一值的路徑(java解題)的解題思路和java代碼,並附上java中常用數據結構的功能函數。 ...
  • 運算符 算術運算符 算數運算符: + - * / // % ** # + var1 = 7 var2 = 90 res = var1 + var2 print(res) # 97 # - var1 = 7 var2 = 90 res = var1 - var2 print(res) # 83 # * ...
  • synchronized 是 Java 語言的一個關鍵字,它允許多個線程同時訪問共用的資源,以避免多線程編程中的競爭條件和死鎖問題。 ...
  • 一 背景 在我們的工作中我們經常有一種場景就是要使用到隊列,特別是對於這樣的一種情況:就是生產的速度明顯快於消費的速度,而且在多線程的環境下消息的生產由多個線程產生消息的消費則沒有這種限制,通過使用隊列這種方式能夠很大程度上將多線程的問題通過入隊的方式變成單個線程內的消息的聚合,然後通過單獨的線程進 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...