在ASP.NET Core中Cookie的使用方法

一.Cookie是什麼?

  我的朋友問我cookie是什麼,用來幹什麼的,可是我居然無法清楚明白簡短地向其闡述cookie,這不禁讓我陷入了沉思:為什麼我無法解釋清楚,我對學習的方法產生了懷疑!所以我們在學習一個東西的時候,一定要做到知其然知其所以然。

  HTTP協議本身是無狀態的。什麼是無狀態呢,即服務器無法判斷用戶身份。Cookie實際上是一小段的文本信息)。客戶端向服務器發起請求,如果服務器需要記錄該用戶狀態,就使用response向客戶端瀏覽器頒發一個Cookie。客戶端瀏覽器會把Cookie保存起來。當瀏覽器再請求該網站時,瀏覽器把請求的網址連同該Cookie一同提交給服務器。服務器檢查該Cookie,以此來辨認用戶狀態。

  打個比方,這就猶如你辦理了銀行卡,下次你去銀行辦業務,直接拿銀行卡就行,不需要身份證。

二.在.NET Core中嘗試

  廢話不多說,幹就完了,現在我們創建ASP.NET Core MVC項目,撰寫該文章時使用的.NET Core SDK 3.0 構建的項目,創建完畢之後我們無需安裝任何包,

  但是我們需要在Startup中添加一些配置,用於Cookie相關的。

<code>//public const string CookieScheme = "YourSchemeName";
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
//CookieAuthenticationDefaults.AuthenticationScheme Cookies Default Value
//you can change scheme
services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)

.AddCookie(options => {
options.LoginPath = "/LoginOrSignOut/Index/";
});
services.AddControllersWithViews();
// is able to also use other services.
//services.AddSingleton<iconfigureoptions>, ConfigureMyCookie>();
}/<iconfigureoptions>/<code>

在其中我們配置登錄頁面,其中 AddAuthentication 中是我們的方案名稱,這個是做什麼的呢?很多小夥伴都懵懵懂懂表示很懵逼啊,我看很多人也是都寫得默認,那它到底有啥用,經過我看AspNetCore源碼發現它這個是可以做一些配置的。看下面的代碼:

<code>internal class ConfigureMyCookie : IConfigureNamedOptions<cookieauthenticationoptions>
{
// You can inject services here
public ConfigureMyCookie()
{}
public void Configure(string name, CookieAuthenticationOptions options)
{
// Only configure the schemes you want
//if (name == Startup.CookieScheme)
//{
// options.LoginPath = "/someotherpath";
//}
}
public void Configure(CookieAuthenticationOptions options)
=> Configure(Options.DefaultName, options);
}/<cookieauthenticationoptions>/<code>

在其中你可以定義某些策略,隨後你直接改變 CookieScheme 的變量就可以替換某些配置,在配置中一共有這幾項,這無疑是幫助我們快速使用Cookie的好幫手~點個贊。

在ASP.NET Core中Cookie的使用方法

在源碼中可以看到Cookie默認保存的時間是14天,這個時間我們可以去選擇,支持TimeSpan的那些類型。

<code>public CookieAuthenticationOptions()
{
ExpireTimeSpan = TimeSpan.FromDays(14);
ReturnUrlParameter = CookieAuthenticationDefaults.ReturnUrlParameter;
SlidingExpiration = true;
Events = new CookieAuthenticationEvents();
}/<code>

接下來LoginOrOut Controller,我們模擬了登錄和退出,通過 SignInAsync 和 SignOutAsync 方法。

<code>[HttpPost]
public async Task<iactionresult> Login(LoginModel loginModel)
{
if (loginModel.Username == "haozi zhang" &&
loginModel.Password == "123456")
{
var claims = new List<claim>
{
new Claim(ClaimTypes.Name, loginModel.Username)
};
ClaimsPrincipal principal = new ClaimsPrincipal(new ClaimsIdentity(claims, "login"));
await HttpContext.SignInAsync(principal);
//Just redirect to our index after logging in.
return Redirect("/Home/Index");
}
return View("Index");
}
/// <summary>
/// this action for web lagout
/// /<summary>
[HttpGet]
public IActionResult Logout()
{
Task.Run(async () =>
{
//註銷登錄的用戶,相當於ASP.NET中的FormsAuthentication.SignOut
await HttpContext.SignOutAsync();
}).Wait();
return View();

}/<claim>/<iactionresult>/<code>

就拿出推出的源碼來看,其中獲取了Handler的某些信息,隨後將它轉換為 IAuthenticationSignOutHandler 接口類型,這個接口 as 接口,像是在地方實現了這個接口,然後將某些運行時的值引用傳遞到該接口上。

<code>public virtual async Task SignOutAsync(HttpContext context, string scheme, AuthenticationProperties properties)
{
if (scheme == null)
{
var defaultScheme = await Schemes.GetDefaultSignOutSchemeAsync();
scheme = defaultScheme?.Name;
if (scheme == null)
{
throw new InvalidOperationException($"No authenticationScheme was specified, and there was no DefaultSignOutScheme found. The default schemes can be set using either AddAuthentication(string defaultScheme) or AddAuthentication(Action<authenticationoptions> configureOptions).");
}
}
var handler = await Handlers.GetHandlerAsync(context, scheme);
if (handler == null)
{
throw await CreateMissingSignOutHandlerException(scheme);
}
var signOutHandler = handler as IAuthenticationSignOutHandler;
if (signOutHandler == null)
{
throw await CreateMismatchedSignOutHandlerException(scheme, handler);
}
await signOutHandler.SignOutAsync(properties);
}/<authenticationoptions>/<code>

其中 GetHandlerAsync 中根據認證策略創建了某些實例,這裡不再多說,因為源碼深不見底,我也說不太清楚...只是想表達一下看源碼的好處和壞處....

<code>public async Task<iauthenticationhandler> GetHandlerAsync(HttpContext context, string authenticationScheme)
{
if (_handlerMap.ContainsKey(authenticationScheme))
{
return _handlerMap[authenticationScheme];
}

var scheme = await Schemes.GetSchemeAsync(authenticationScheme);
if (scheme == null)
{
return null;
}
var handler = (context.RequestServices.GetService(scheme.HandlerType) ??
ActivatorUtilities.CreateInstance(context.RequestServices, scheme.HandlerType))
as IAuthenticationHandler;
if (handler != null)
{
await handler.InitializeAsync(scheme, context);
_handlerMap[authenticationScheme] = handler;
}
return handler;
}/<iauthenticationhandler>/<code>

最後我們在頁面上想要獲取登錄的信息,可以通過 HttpContext.User.Claims 中的簽名信息獲取。

<code>@using Microsoft.AspNetCore.Authentication

HttpContext.User.Claims



@foreach (var claim in User.Claims)
{
@claim.Type

@claim.Value

}

AuthenticationProperties



@foreach (var prop in (await Context.AuthenticateAsync()).Properties.Items)
{
@prop.Key

@prop.Value

}
/<code>

三.最後效果以及源碼地址

在ASP.NET Core中Cookie的使用方法


分享到:


相關文章: