<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      C# Web開發教程(九)標識框架[Identity]

      標識(Identity)框架

      • AuthenticationAuthorization
      - Authentication: 認證,你是誰
      - Authorization: 權限,你有什么權限
      
      • 1、標識(Identity)框架: 采用基于角色(Role)的訪問控制
      - (Role-Based Access Control,簡稱RBAC)策略,內置了對用戶、角色等表的管理以及相關的接口,支持外部登錄、2FA等。
      - 標識框架使用EF Core對數據庫進行操作,因此標識框架支持幾乎所有數據庫。
      
      • Identity框架使用
          - IdentityUser<TKey>、IdentityRole<TKey>,TKey代表主鍵的類型。我們一般編寫繼承自ldentityUser<TKey>、IdentityRole<TKey>等的自定義類,可以增加自定義屬性。
          - NuGet安裝: 
          	- Install-Package Microsoft.EntityFrameworkCore -Version 6.0.0
          	- Install-Package Microsoft.EntityFrameworkCore.SqlServer -Version 6.0.0
          	- Install-Package Microsoft.EntityFrameworkCore.Tools -Version 6.0.0
          	- Install-Package Microsoft.AspNetCore.Identity.EntityFrameworkCore  -Version 6.0.0
          - 創建繼承自ldentityDbContext的類
          - 可以通過ldDbContext類來操作數據庫,不過框架中提供了RoleManager、UserManager等類來簡化對數據庫的操作。
          - 部分方法的返回值為Task<IdentityResult>類型
      
      
      
      // MyUser.cs
      
      using Microsoft.AspNetCore.Identity;
      
      namespace WebApplicationAboutIdentity
      {
      	// 默認的 IdentityUser 使用 string 類型主鍵,這里改為 long
          public class MyUser:IdentityUser<long>
          {
          }
      }
      
      // MyRole.cs
      using Microsoft.AspNetCore.Identity;
      
      namespace WebApplicationAboutIdentity
      {
          public class MyRole:IdentityRole<long>
          {
          }
      }
      
      // MyDbContext.cs
      
      using Microsoft.AspNetCore.Identity;
      using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
      using Microsoft.EntityFrameworkCore;
      
      namespace WebApplicationAboutIdentity
      {
      	// 繼承 IdentityDbContext,指定自定義的用戶類型、角色類型和主鍵類型
      	// 會自動創建 Identity 相關的所有表(Users、Roles、UserRoles 等)
          public class MyDbContext : IdentityDbContext<MyUser,MyRole,long>
          {
              public MyDbContext(DbContextOptions<MyDbContext> options) : base(options)
              {
              }
          }
      }
      
      // DbContextDesignTimeFactory.cs
      
      using Microsoft.EntityFrameworkCore;
      using Microsoft.EntityFrameworkCore.Design;
      
      namespace WebApplicationAboutIdentity
      {
          public class DbContextDesignTimeFactory: IDesignTimeDbContextFactory<MyDbContext>
          {
              public MyDbContext CreateDbContext(string[] args)
              {
              	// 配置數據庫連接,用于 EF Core 遷移命令
                  DbContextOptionsBuilder<MyDbContext> builder = new DbContextOptionsBuilder<MyDbContext>();
                  string connStr = "Server=.;Database=idtest1;Trusted_Connection=True;";
                  builder.UseSqlServer(connStr);
                  MyDbContext ctx = new MyDbContext(builder.Options);
                  return ctx;
              }
          }
      }
      
      // Program.cs
      
      ......
      using Microsoft.AspNetCore.Identity;
      using Microsoft.EntityFrameworkCore;
      using WebApplicationAboutIdentity;
      
      var builder = WebApplication.CreateBuilder(args);
      ......
      
      // 數據庫配置
      builder.Services.AddDbContext<MyDbContext>(opt =>
      {
          opt.UseSqlServer("Server=.;Database=idtest1;Trusted_Connection=True;");
      });
      // Identity 配置
      builder.Services.AddDataProtection();
      builder.Services.AddIdentityCore<MyUser>(options =>
      {
      	// 簡化密碼策略
          options.Password.RequireDigit = false;
          options.Password.RequiredLength = 6;
          options.Password.RequireLowercase = false;
          options.Password.RequireNonAlphanumeric = false;
          options.Password.RequireUppercase = false;
          // 設置令牌提供程序
          options.Tokens.PasswordResetTokenProvider = TokenOptions.DefaultEmailProvider;
          options.Tokens.EmailConfirmationTokenProvider = TokenOptions.DefaultEmailProvider;
      });
      // Identity 構建器
      // 指定用戶和角色類型,配置使用 Entity Framework 存儲,添加默認令牌提供程序,注冊用戶管理器和角色管理器
      IdentityBuilder idBuilder = new(typeof(MyUser),typeof(MyRole),builder.Services);
      idBuilder.AddEntityFrameworkStores<MyDbContext>().AddDefaultTokenProviders().AddUserManager<UserManager<MyUser>>().AddRoleManager<RoleManager<MyRole>>();
      
      var app = builder.Build();
      ......
      
      app.Run();
      
      - 最后,作數據庫遷移并更新數據庫
      
      • 小結:這個配置為應用程序提供了完整的用戶認證和授權基礎架構
      - 自定義主鍵類型: 使用 long 代替默認的 string
      - 簡化的密碼策略: 降低了密碼復雜度要求
      - 完整的 Identity 功能: 包含用戶管理、角色管理、令牌生成等
      - SQL Server 存儲: 使用 Entity Framework Core 和 SQL Server
      

      數據庫

      Identity Demo 演示---UserManager和RoleManager

      • 演示接口: 使用 ASP.NET Core Identity 進行身份管理和授權的控制器代碼
      using Microsoft.AspNetCore.Identity;
      using Microsoft.AspNetCore.Mvc;
      
      namespace WebApplicationAboutIdentity.Controllers
      {
          [Route("api/[controller]/[action]")]
          [ApiController]
          public class DemoController : ControllerBase
          {
             
      		// 依賴注入
              private readonly UserManager<MyUser> userManager;
              private readonly RoleManager<MyRole> roleManager;
      
              public DemoController(UserManager<MyUser> userManager, RoleManager<MyRole> roleManager)
              {
                  this.userManager = userManager;
                  this.roleManager = roleManager;
              }
      
              [HttpPost]
              public async Task<ActionResult<string>> Test1()
              {
              	// 檢查 "admin" 角色是否存在,如果不存在就創建該角色
                  if (await roleManager.RoleExistsAsync("admin") == false)
                  {
                      MyRole role = new() { Name = "admin" };
                      var result = await roleManager.CreateAsync(role);
                      if (!result.Succeeded) return BadRequest("roleManage.CreateAsync failed");
                  }
      			
      			// 查找用戶名為 "yzk" 的用戶,如果用戶不存在,創建新用戶并設置密碼為 "123456"
                  MyUser user1 = await userManager.FindByNameAsync("yzk");
      
                  if (user1 == null)
                  {
                      user1 = new() { UserName = "yzk" };
                      var result = await userManager.CreateAsync(user1, "123456");
                      if (!result.Succeeded) return BadRequest("userManage.CreateAsync failed");
                  }
      			
      			// 檢查user1是否已在 "admin" 角色中,如果不在,就將用戶添加到該角色
                  if(!await userManager.IsInRoleAsync(user1, "admin"))
                  {
                      var result = await userManager.AddToRoleAsync(user1, "admin");
                      if (!result.Succeeded) return BadRequest("userManage.AddToRoleAsync failed");
                  }
      
                  return "ok";
              }
      
          }   
      }
      
      
      • 演示接口: 完成用戶密碼驗證
      // CheckPwdRequest.cs
      
      namespace WebApplicationAboutIdentity
      {
      	// 使用 record 類型定義請求數據模型,這是一個不可變的數據傳輸對象
      	// 含兩個屬性:UserName(用戶名)和 Password(密碼)
      	// 用途: 匹配前端傳過來的UerName和Password
          public record CheckPwdRequest(string UserName, string Password);
      }
      
      // 主程序
      
      ......
      [HttpPost]								// 接收前端傳過來的參數
      public async Task<ActionResult> CheckPwd(CheckPwdRequest req)
      {
          string userName = req.UserName;
          string pwd = req.Password;
          var user = await userManager.FindByNameAsync(userName);
          if(user == null)
          {
              // 在開發環境顯示詳細錯誤,生產環境返回模糊錯誤,避免信息泄露
              if (hostEnvironment.IsDevelopment())
              {
                  return BadRequest("用戶名不存在");
              }
              else
              {
                  return BadRequest();
              }
          }
      	
      	// 檢查用戶是否因多次登錄失敗被鎖定,如果鎖定,返回鎖定結束時間
          if (await userManager.IsLockedOutAsync(user)) return BadRequest("用戶已被鎖定,結束時間" + user.LockoutEnd);
          // 驗證密碼哈希
          if (await userManager.CheckPasswordAsync(user,pwd))
          {
          	// 驗證成功后重置失敗計數(清零)
              await userManager.ResetAccessFailedCountAsync(user);
              return Ok("登錄成功");
          }
          else
          {
          	// AccessFailedAsync 記錄一次登錄失敗,達到閾值會自動鎖定用戶
              await userManager.AccessFailedAsync(user);
              return BadRequest("用戶名或密碼錯誤");
          }
      }
      
      • 接口演示: 重置密碼流程

        • 生成重置Token,發給用戶(短信,郵箱),用戶根據Token完成密碼的重置
          • 說明事項: 為了演示實例的簡單,發送的邏輯改為控制臺輸出Token
        [HttpPost]
        public async Task<ActionResult> SendResetPasswordToken(string userName)
        {
            var user = await userManager.FindByNameAsync(userName);
            if (user == null)
            {
                return BadRequest("用戶名不存在");
            }
            string token = await userManager.GeneratePasswordResetTokenAsync(user);
            Console.WriteLine($"驗證碼是{token}"); // 驗證碼是758683
            return Ok();
        }
        
        // Program.cs
        ......
        builder.Services.AddIdentityCore<MyUser>(options =>
        {
            ......
            // 如果注釋掉,Token就是一堆長長的字符串
            options.Tokens.PasswordResetTokenProvider = TokenOptions.DefaultEmailProvider;
            ......
        });
        
        • 用戶帶著用戶名,驗證碼新密碼,完成重置密碼流程
        [HttpPut]
        public async Task<ActionResult> ResetPassword(string userName,string token,string newPassword)
        {
            var user = await userManager.FindByNameAsync(userName);
            if (user == null) return BadRequest("用戶名不存在");
            var result = await userManager.ResetPasswordAsync(user,token,newPassword);
            if (result.Succeeded)
            {
                await userManager.ResetAccessFailedCountAsync(user);
                return Ok("密碼重置成功");
            }
            else
            {
                await userManager.AccessFailedAsync(user);
                return BadRequest("密碼重置失敗");
            }
        }
        
      posted @ 2025-10-27 11:14  清安寧  閱讀(7)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 国产a在视频线精品视频下载| 真人性囗交视频| 成人AV无码一区二区三区| 国内极度色诱视频网站| 影音先锋人妻啪啪av资源网站| 久久精品国产亚洲av品| 精品人妻日韩中文字幕| 国产-第1页-浮力影院| 无码日韩人妻精品久久| 亚洲精品第一区二区三区| 少妇被粗大的猛烈进出69影院一| 国产精品色内内在线播放| 日韩精品一区二区三区在线观看| 97国产揄拍国产精品人妻| 国产精品久久久久久福利69堂| 亚洲精品一区三区三区在| 日韩福利视频导航| 国产极品美女高潮抽搐免费网站| 国产精品免费看久久久| 国产成人高清亚洲综合| 欧美精品一产区二产区| 久久精产国品一二三产品| 精品国产av一二三四区| 精品国产人妻一区二区三区久久 | 午夜男女爽爽影院在线| 影音先锋大黄瓜视频| 久热视频这里只有精品6| 金沙县| a在线观看视频在线播放| 国产精品一区在线蜜臀| 激情五月开心综合亚洲| 国产一区二区三区18禁| 久久成人国产精品免费软件 | 91精品国产午夜福利| 伊人色综合久久天天| 狠狠躁夜夜躁人人爽天天bl| 国产精品va无码一区二区| 国产福利姬喷水福利在线观看| 少妇被无套内谢免费看| 日韩人妻无码一区二区三区| 青青草原网站在线观看|