3分钟快速学会在ASP.NET Core MVC中如何使用Cookie
一.cookie是什么?
我的朋友问我cookie是什么,用来干什么的,可是我居然无法清楚明白简短地向其阐述cookie,这不禁让我陷入了沉思:为什么我无法解释清楚,我对学习的方法产生了怀疑!所以我们在学习一个东西的时候,一定要做到知其然知其所以然。
http协议本身是无状态的。什么是无状态呢,即服务器无法判断用户身份。cookie实际上是一小段的文本信息)。客户端向服务器发起请求,如果服务器需要记录该用户状态,就使用response向客户端浏览器颁发一个cookie。客户端浏览器会把cookie保存起来。当浏览器再请求该网站时,浏览器把请求的网址连同该cookie一同提交给服务器。服务器检查该cookie,以此来辨认用户状态。
打个比方,这就犹如你办理了银行卡,下次你去银行办业务,直接拿银行卡就行,不需要身份证。
二.在.net core中尝试
废话不多说,干就完了,现在我们创建asp.net core mvc项目,撰写该文章时使用的.net core sdk 3.0 构建的项目,创建完毕之后我们无需安装任何包,
但是我们需要在startup中添加一些配置,用于cookie相关的。
//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<cookieauthenticationoptions>, configuremycookie>(); }
在其中我们配置登录页面,其中 addauthentication 中是我们的方案名称,这个是做什么的呢?很多小伙伴都懵懵懂懂表示很懵逼啊,我看很多人也是都写得默认,那它到底有啥用,经过我看aspnetcore源码发现它这个是可以做一些配置的。看下面的代码:
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); }
在其中你可以定义某些策略,随后你直接改变 cookiescheme 的变量就可以替换某些配置,在配置中一共有这几项,这无疑是帮助我们快速使用cookie的好帮手~点个赞。
在源码中可以看到cookie默认保存的时间是14天,这个时间我们可以去选择,支持timespan的那些类型。
public cookieauthenticationoptions() { expiretimespan = timespan.fromdays(14); returnurlparameter = cookieauthenticationdefaults.returnurlparameter; slidingexpiration = true; events = new cookieauthenticationevents(); }
接下来loginorout controller,我们模拟了登录和退出,通过 signinasync 和 signoutasync 方法。
[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(); }
就拿出推出的源码来看,其中获取了handler的某些信息,随后将它转换为 iauthenticationsignouthandler 接口类型,这个接口 as 接口,像是在地方实现了这个接口,然后将某些运行时的值引用传递到该接口上。
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); }
其中 gethandlerasync 中根据认证策略创建了某些实例,这里不再多说,因为源码深不见底,我也说不太清楚...只是想表达一下看源码的好处和坏处....
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; }
最后我们在页面上想要获取登录的信息,可以通过 httpcontext.user.claims 中的签名信息获取。
@using microsoft.aspnetcore.authentication <h2>httpcontext.user.claims</h2> <dl> @foreach (var claim in user.claims) { <dt>@claim.type</dt> <dd>@claim.value</dd> } </dl> <h2>authenticationproperties</h2> <dl> @foreach (var prop in (await context.authenticateasync()).properties.items) { <dt>@prop.key</dt> <dd>@prop.value</dd> } </dl>
三.最后效果以及源码地址#
github地址:https://github.com/zaranetcore/aspnetcore_jsonwebtoken/tree/master/src/identity.cookie/dotnetcore_cookie_sample
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对的支持。
上一篇: mysql-调优