.net core 認證與授權(二)


前言

這篇緊接着一來寫的,在第一篇中介紹了認證與授權,同時提出了這套機制其實就是模擬現實中的認證與授權。
同樣這篇介紹在這套機制下,用戶信息管理機制?這里就會問了,上一篇中認證和授權不是都ok了嗎,怎么會有一個管理機制呢?當然並不一定要使用下面這套機制,但是給了我們很大的啟發。
在上一結中我們頒發證書是這樣的:

public IActionResult Authenticate()
{
    var SchoolClaims = new List<Claim>()
    {
        new Claim(ClaimTypes.Name,"Jack"),
        new Claim(ClaimTypes.Email,"Jack@fmail.com")
    };

    var LicensClaims = new List<Claim>()
    {
        new Claim(ClaimTypes.Name,"Jack.li"),
        new Claim(ClaimTypes.Email,"Jack@fmail.com"),
        new Claim("begin","2000.10.1")
    };
    var SchoolIdentity = new ClaimsIdentity(SchoolClaims,"Student Identity");
    var CarManagerIdentity = new ClaimsIdentity(LicensClaims, "Licens Identity");
    var userPrincipal = new ClaimsPrincipal(new[] { SchoolIdentity, CarManagerIdentity });
    
    HttpContext.SignInAsync(userPrincipal);
    return RedirectToAction("Index");
}

有沒有發現new Claim(ClaimTypes.Name,"Jack") 寫死了?我的信息是要從數據庫里面查啊。
這時候微軟的框架就跳出來了,說用我的這套機制,幫你搞定,到底是什么機制呢?請看正文。小聲逼逼一句,微軟就喜歡搞全包工程。
正文均為個人理解,如有不對請指出。

正文

首先提及到一個結構,IdentityUser,這東西是真的博大精深,但是感覺有點臃腫,這很微軟。
IdentityUser 這里可以簡單說明一下,就是存儲用戶信息的地方。
既然說到用戶存儲,那么就要提及到數據庫了。
創建了一個AppDbContext:

public class AppDbContext:IdentityDbContext
{
	public AppDbContext(DbContextOptions<AppDbContext> options):base(options)
	{

	}
}

以前我們一般是繼承DbContext,DbContext是Ef的上下文。
這里IdentityDbContext,是Ef的擴展,看下我添加了什么。

紅色框內是我添加的。
在這里我為了演示使用內存數據庫memory,所以我多加了一個庫。
然后我在startup中配置使用memory數據庫。

 services.AddDbContext<AppDbContext>(config =>{
                config.UseInMemoryDatabase("Memery");
            });

這樣就配置了,現在就解決了數據庫的問題。
同樣需要配置identity:

services.AddIdentity<IdentityUser, IdentityRole>(config=> {
                config.Password.RequiredLength = 4;
                config.Password.RequireDigit = false;
                config.Password.RequireNonAlphanumeric = false;
                config.Password.RequireLowercase = false;
                config.Password.RequireUppercase = false;
            }).AddEntityFrameworkStores<AppDbContext>().AddDefaultTokenProviders();

有幾個關鍵的地方,就是config.Password.RequiredLength = 4;等幾個password的配置,
因為identetyUser 有默認的機制就是密碼必須要大寫,然后不小於6位密碼等,我們在這里全部去掉。
AddEntityFrameworkStores () 添加EF 存儲實現。
AddDefaultTokenProviders() 默認提供生成token。這種token 用來干啥呢?當然是用來證明用戶的了。比如我們修改密碼的時候,我們發現鏈接上有一個token,異曲同工之妙哈。

services.ConfigureApplicationCookie(config =>
{
	config.Cookie.Name = "Identity.Cooke";
	config.LoginPath = "/Home/Login";
});

加上驗證,當沒有登陸的時候去到登陸頁面。
好的配置我們基本完成了。
接下來就是去實現登陸與注冊。

public IActionResult Index()
{
	return View();
}
public IActionResult Secret()
{
	return View();
}

public IActionResult Login()
{
	return View();
}

public IActionResult Register()
{
	return View();
}
[HttpPost]
public async Task<IActionResult> Login(string username, string password)
{
	var user = await _userManager.FindByNameAsync(username);
	if (user != null)
	{
		//sign in
	   var Signresult= await  _signInManager.PasswordSignInAsync(user,password,false,false);
		if (Signresult.Succeeded)
		{
			return RedirectToAction("Secret");
		}
	}
	return RedirectToAction("Index");
}
[HttpPost]
public async Task<IActionResult>  Register(string username,string password)
{

	var user = new IdentityUser
	{
		UserName = username,
		Email = ""
	};

	var result=await _userManager.CreateAsync(user,password);
	if (result.Succeeded)
	{
		var Signresult = await _signInManager.PasswordSignInAsync(user, password, false, false);
		if (Signresult.Succeeded)
		{
			return RedirectToAction("Index");
		}
	}
	return RedirectToAction("Index");
}

看到兩個http post:
先看Register:
創建了IdentityUser,用來存儲用戶信息。
_userManager 是用來管理user用戶的,比如說創建,刪除,修改,是identetyUser 內部機制。
創建過程如下:

public HomeController(UserManager<IdentityUser> userManager,SignInManager<IdentityUser> signInManager)
{
	_userManager = userManager;
	_signInManager = signInManager;
}

var result=await _userManager.CreateAsync(user,password); 如果創建用戶成功,那么就進行登陸如下:

var Signresult = await _signInManager.PasswordSignInAsync(user, password, false, false);

注意PasswordSignInAsync登陸的話會產生token,用於驗證我們是否登陸。
當我注冊后,產生了token,如下:

看下登陸,其實我們在注冊部分就已經介紹了登陸了。
我重新把代碼放下了:

var user = await _userManager.FindByNameAsync(username);
if (user != null)
{
	//sign in
   var Signresult= await  _signInManager.PasswordSignInAsync(user,password,false,false);
	if (Signresult.Succeeded)
	{
		return RedirectToAction("Secret");
	}
}
return RedirectToAction("Index");

發現就多了一步,根據名字去查找user,如果有這個user,然后去比較密碼。和平時寫code 差不多。
然后登陸后就可以進入了我們想進入的頁面。
如果我們想loginout:

public async Task<IActionResult> Logout()
{
	await _signInManager.SignOutAsync();
	return RedirectToAction("Index");
}

把登陸和注冊的頁面貼下:
login:

<form action="/Home/Login" method="post">
    <input type="text" name="username" value="" />
    <input type="password" name="password" value="" />
    <button type="submit">登陸</button>
</form>

注冊:

<form action="/Home/Register" method="post">
    <input type="text" name="username" value="" />
    <input type="password" name="password" value="" />
    <button type="submit">注冊</button>
</form>

在上一篇中,就很疑問了,上一篇沒有登錄啊。
真的沒有登錄嗎?只是用證書去登錄了,不然怎么能過的了檢查呢。

HttpContext.SignInAsync("CookieAuth", userPrincipal);

總結

現在我們的流程更加的明顯了,先要驗證用戶信息,比如說是否登錄了,這個過程相當於什么呢?我們用我們的名字和指紋(password),去獲取到了我們的身份證。有了這張身份證后我們才有其他的證書,然后才有根據證書去獲取一些權限。
后續介紹基本的配置,與原理。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM