Configure Identity services
ติดตั้ง ASP.NET Core scaffolder
[code]
> dotnet tool install -g dotnet-aspnet-codegenerator
[/code]
เข้าไปใน project directory แล้วทำการ add package Microsoft.VisualStudio.Web.CodeGeneration.Design
[code]
> dotnet add package Microsoft.VisualStudio.Web.CodeGeneration.Design
> dotnet restore
[/code]
สั่ง scaffolder
ข้อควรระวังคือ -dc webAppIdentity.Data.ApplicationDbContext ต้องเป็นชื่อโปรเจ็กส์ที่ถูกต้องทั้งตัวพิมพ์เล็กพิมพ์ใหญ่
ไม่งั้นตอนรันจะ error ฟ้องว่ามี 2 schema
แสดงไฟล์ที่เกี่ยวข้องกับ Account.Register , Account.Login , Account.Logout ออกมา
[code]
> dotnet aspnet-codegenerator identity -dc webAppIdentity.Data.ApplicationDbContext –files "Account.Register;Account.Login;Account.Logout"
[/code]
หรือ scaffolder ไฟล์ทั้งหมดออกมาเลย (เยอะมาก)
[code]
> dotnet aspnet-codegenerator identity -dc webAppIdentity.Data.ApplicationDbContext
[/code]
แต่อย่าลืมกำหนดชื่อโปรเจ็กส์ด้วยนะ ในที่นี้ใช้ webAppIdentity
Areas/identity/Pages/Account/Register.cshtml.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 |
using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.Text.Encodings.Web; using System.Threading.Tasks; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Identity.UI.Services; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.RazorPages; using Microsoft.Extensions.Logging; namespace webAppIdentity.Areas.Identity.Pages.Account { [AllowAnonymous] public class RegisterModel : PageModel { private readonly SignInManager<IdentityUser> _signInManager; private readonly UserManager<IdentityUser> _userManager; private readonly ILogger<RegisterModel> _logger; private readonly IEmailSender _emailSender; public RegisterModel( UserManager<IdentityUser> userManager, SignInManager<IdentityUser> signInManager, ILogger<RegisterModel> logger, IEmailSender emailSender) { _userManager = userManager; _signInManager = signInManager; _logger = logger; _emailSender = emailSender; } [BindProperty] public InputModel Input { get; set; } public string ReturnUrl { get; set; } public class InputModel { [Required] [EmailAddress] [Display(Name = "Email")] public string Email { get; set; } [Required] [StringLength(100, ErrorMessage = "The {0} must be at least {2} and at max {1} characters long.", MinimumLength = 6)] [DataType(DataType.Password)] [Display(Name = "Password")] public string Password { get; set; } [DataType(DataType.Password)] [Display(Name = "Confirm password")] [Compare("Password", ErrorMessage = "The password and confirmation password do not match.")] public string ConfirmPassword { get; set; } } public void OnGet(string returnUrl = null) { ReturnUrl = returnUrl; } public async Task<IActionResult> OnPostAsync(string returnUrl = null) { returnUrl = returnUrl ?? Url.Content("~/"); if (ModelState.IsValid) { var user = new IdentityUser { UserName = Input.Email, Email = Input.Email }; var result = await _userManager.CreateAsync(user, Input.Password); if (result.Succeeded) { _logger.LogInformation("User created a new account with password."); var code = await _userManager.GenerateEmailConfirmationTokenAsync(user); var callbackUrl = Url.Page( "/Account/ConfirmEmail", pageHandler: null, values: new { userId = user.Id, code = code }, protocol: Request.Scheme); await _emailSender.SendEmailAsync(Input.Email, "Confirm your email", $"Please confirm your account by <a href='{HtmlEncoder.Default.Encode(callbackUrl)}'>clicking here</a>."); await _signInManager.SignInAsync(user, isPersistent: false); return LocalRedirect(returnUrl); } foreach (var error in result.Errors) { ModelState.AddModelError(string.Empty, error.Description); } } // If we got this far, something failed, redisplay form return Page(); } } } |
Areas/identity/Pages/Account/Login.cshtml.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 |
using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.Linq; using System.Threading.Tasks; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Authentication; using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.RazorPages; using Microsoft.Extensions.Logging; namespace webAppIdentity.Areas.Identity.Pages.Account { [AllowAnonymous] public class LoginModel : PageModel { private readonly SignInManager<IdentityUser> _signInManager; private readonly ILogger<LoginModel> _logger; public LoginModel(SignInManager<IdentityUser> signInManager, ILogger<LoginModel> logger) { _signInManager = signInManager; _logger = logger; } [BindProperty] public InputModel Input { get; set; } public IList<AuthenticationScheme> ExternalLogins { get; set; } public string ReturnUrl { get; set; } [TempData] public string ErrorMessage { get; set; } public class InputModel { [Required] [EmailAddress] public string Email { get; set; } [Required] [DataType(DataType.Password)] public string Password { get; set; } [Display(Name = "Remember me?")] public bool RememberMe { get; set; } } public async Task OnGetAsync(string returnUrl = null) { if (!string.IsNullOrEmpty(ErrorMessage)) { ModelState.AddModelError(string.Empty, ErrorMessage); } returnUrl = returnUrl ?? Url.Content("~/"); // Clear the existing external cookie to ensure a clean login process await HttpContext.SignOutAsync(IdentityConstants.ExternalScheme); ExternalLogins = (await _signInManager.GetExternalAuthenticationSchemesAsync()).ToList(); ReturnUrl = returnUrl; } public async Task<IActionResult> OnPostAsync(string returnUrl = null) { returnUrl = returnUrl ?? Url.Content("~/"); if (ModelState.IsValid) { // This doesn't count login failures towards account lockout // To enable password failures to trigger account lockout, set lockoutOnFailure: true var result = await _signInManager.PasswordSignInAsync(Input.Email, Input.Password, Input.RememberMe, lockoutOnFailure: true); if (result.Succeeded) { _logger.LogInformation("User logged in."); return LocalRedirect(returnUrl); } if (result.RequiresTwoFactor) { return RedirectToPage("./LoginWith2fa", new { ReturnUrl = returnUrl, RememberMe = Input.RememberMe }); } if (result.IsLockedOut) { _logger.LogWarning("User account locked out."); return RedirectToPage("./Lockout"); } else { ModelState.AddModelError(string.Empty, "Invalid login attempt."); return Page(); } } // If we got this far, something failed, redisplay form return Page(); } } } |
Areas/identity/Pages/Account/Logout.cshtml.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.RazorPages; using Microsoft.Extensions.Logging; namespace webAppIdentity.Areas.Identity.Pages.Account { [AllowAnonymous] public class LogoutModel : PageModel { private readonly SignInManager<IdentityUser> _signInManager; private readonly ILogger<LogoutModel> _logger; public LogoutModel(SignInManager<IdentityUser> signInManager, ILogger<LogoutModel> logger) { _signInManager = signInManager; _logger = logger; } public void OnGet() { } public async Task<IActionResult> OnPost(string returnUrl = null) { await _signInManager.SignOutAsync(); _logger.LogInformation("User logged out."); if (returnUrl != null) { return LocalRedirect(returnUrl); } else { return Page(); } } } } |
รายชื่อไฟล์ที่สามารถเรียกออกมาได้
[code]
Account.Register
Account.Login
Account.Logout
Account.AccessDenied
Account.ConfirmEmail
Account.ExternalLogin
Account.ForgotPassword
Account.ForgotPasswordConfirmation
Account.LoginWith2fa
Account.LoginWithRecoveryCode
Account.ResetPassword
Account.ResetPasswordConfirmation
Account.Manage.ChangePassword
Account.Manage.DeletePersonalData
Account.Manage.Disable2fa
Account.Manage.DownloadPersonalData
Account.Manage.EnableAuthenticator
Account.Manage.ExternalLogins
Account.Manage.GenerateRecoveryCodes
Account.Manage.Index
Account.Manage.PersonalData
Account.Manage.ResetAuthenticator
Account.Manage.SetPassword
Account.Manage.TwoFactorAuthentication
[/code]
Link