1. 程式人生 > 實用技巧 >ASP.Net Core -- Identity

ASP.Net Core -- Identity

ASP.Net Core Identity是ASP.Net Core預設的內建的身份認證授權系統,可以管理成員,角色等等之類的東西,預設使用的是Microsoft SqlServer,然後,它也支援外部的身份認證。

• 寫個小例子,學習記錄一下:

一個控制器:AccountController;兩個檢視:Login和Register;兩個模型類:LoginViewModel.cs和RegisterViewModel.cs

• ASP.Net Core Identity重點類:

UserManager<IdentityUser>:用來操作使用者,比如:刪除使用者,新增使用者....並把處理結果儲存在一個地方,預設使用的SqlServer

SignInManager<IdentityUser>:主要用來對使用者的身份認證的

• 程式碼示例:

新建一個AccountController控制器,並且注入以上兩個重點類:

public class AccountController : Controller
    {
        private readonly SignInManager<IdentityUser> _signInManager;
        private readonly UserManager<IdentityUser> _userManager;
        public AccountController(SignInManager<IdentityUser> signInManager, 
            UserManager<IdentityUser> userManager)
        {
            _signInManager = signInManager;
            _userManager = userManager;
        }
        public IActionResult Login() {
            return View();
        }
        [HttpPost]
        public async Task<IActionResult> Login(LoginViewModel loginViewModel)
        {
            if (!ModelState.IsValid)
            {
                return View(loginViewModel);
            }
            var user = await _userManager.FindByNameAsync(loginViewModel.UserName);

            if (user != null)
            {
                var result = await _signInManager.PasswordSignInAsync(user, loginViewModel.Password, false, false);
                if (result.Succeeded)
                {
                    return RedirectToAction("Index", "Home");
                }
            }
            ModelState.AddModelError("", "使用者名稱或密碼不正確");
            return View(loginViewModel);
        }
        public IActionResult Register()
        {
            return View();
        }
        [HttpPost]
        public async Task<IActionResult> Register(RegisterViewModel registerViewModel)
        {
            if (ModelState.IsValid) 
            {
                var user = new IdentityUser
                {
                    UserName = registerViewModel.UserName
                };
                var result = await _userManager.CreateAsync(user, registerViewModel.Password);

                if (result.Succeeded)
                {
                    return RedirectToAction("Index", "Home");
                }
            };

            return View(registerViewModel);
        }
        public async Task<IActionResult> logout()
        {
            await _signInManager.SignOutAsync();

            return RedirectToAction("Index", "Home");
        }

Login檢視:

@model LoginViewModel
<h2>請登入或者<a asp-action="Register" asp-controller="Account">註冊</a></h2>
<form asp-action="Login" asp-controller="Account" method="post">
    <div>
        <label asp-for="UserName"></label>
        <input  asp-for="UserName"/>
        <span asp-validation-for="UserName"></span>
    </div>
    <div>
        <label asp-for="Password"></label>
        <input asp-for="Password" />
        <span asp-validation-for="Password"></span>
    </div>
    <div>
        <input type="submit" value="提交" />
    </div>
    <div asp-validation-summary="All"></div>
</form>

Register檢視:

@model RegisterViewModel
<h2>註冊</h2>
<form asp-action="Register" asp-controller="Account" method="post">
    <div>
        <label asp-for="UserName"></label>
        <input asp-for="UserName" />
        <span asp-validation-for="UserName"></span>
    </div>
    <div>
        <label asp-for="Password"></label>
        <input asp-for="Password" />
        <span asp-validation-for="Password"></span>
    </div>
    <div>
        <input type="submit" value="提交" />
    </div>
    <div asp-validation-summary="All"></div>
</form>

Layout佈局頁:

<!DOCTYPE html>
@using Microsoft.AspNetCore.Identity
@inject SignInManager<IdentityUser> SignInManager
<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title></title>
    <link href="~/node_modules/bootstrap/dist/css/bootstrap.css" rel="stylesheet" />
</head>
<body>
    <nav class="navbar navbar-light bg-light">
        <a class="navbar-brand" href="#">Navbar</a>
        @if (SignInManager.IsSignedIn(User))
        {
            <form asp-action="Logout" asp-controller="Account" method="post" id="logoutForm">
                <ul class="navbar-nav mr-auto">
                    <li>
                        <a href="javascript:document.getElementById('logoutForm').submit()">登出</a>
                    </li>
                </ul>
            </form>
        }
        else
        {
            <ul class="navbar-nav mr-auto">
                <li>
                    <a asp-action="Register" asp-controller="Account">註冊</a>
                </li>
                <li>
                    <a asp-action="Login" asp-controller="Account">登入</a>
                </li>
            </ul>
        }
    </nav>
    <div>
        @RenderBody()
    </div>
    <script src="~/node_modules/jquery/dist/jquery.js"></script>
    <script src="~/node_modules/jquery-validation/dist/jquery.validate.js"></script>
    <script src="~/node_modules/jquery-validation-unobtrusive/dist/jquery.validate.unobtrusive"></script>
</body>
</html>

LoginViewModel.cs和RegisterViewModel.cs內容一樣,如下:

public class LoginViewModel
    {
        [Required]
        [Display(Name ="使用者名稱")]
        public string   UserName { get; set; }
        [Required]
        [Display(Name ="密碼")]
        [DataType(DataType.Password)]
        public string Password { get; set; }
    }

最後,註冊服務,進行資料遷移:

在startup.cs註冊服務:

services.AddDbContext<IdentityDbContext>(options => options.UseMySql(_configuration.GetConnectionString("MysqlConnection"),b=>b.MigrationsAssembly("Tutorials.Web")));
            services.AddDefaultIdentity<IdentityUser>().AddEntityFrameworkStores<IdentityDbContext>();

            services.Configure<IdentityOptions>(options =>
            {
                // Password settings.
                options.Password.RequireDigit = false;
                options.Password.RequireLowercase = false;
                options.Password.RequireNonAlphanumeric = false;
                options.Password.RequireUppercase = false;
                options.Password.RequiredLength = 1;
                options.Password.RequiredUniqueChars = 1;

                // Lockout settings.
                options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(5);
                options.Lockout.MaxFailedAccessAttempts = 5;
                options.Lockout.AllowedForNewUsers = false;

                // User settings.
                options.User.AllowedUserNameCharacters =
                "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._@+";
                options.User.RequireUniqueEmail = false;
            });

在Configure理新增:

app.UseAuthentication();

然後進行遷移,開啟Nuget包控制檯,首先輸入遷移命令:

Add-migration initialIdentity -Context IdentityDbContext

然後輸入更新資料庫命令:

update database -Context IdentityDbContext

這個時候,資料庫中會多幾張表,使用者存放使用者資訊。這樣,一個小demo就實現了,使用者登入,註冊,登入成功或者註冊成功後跳轉到index頁,並隱藏登入和註冊按鈕,顯示登出按鈕。