3 minutes to quickly learn how to use cookies in asp.net core MVC

Time:2020-3-23

1、 What is a cookie?

My friend asked me what cookies are and what they are used for, but I couldn’t explain them clearly and briefly, which led me to ponder: why can’t I explain clearly, and I have doubts about the method of learning! So when we are learning something, we must know what it is and why it is.

The HTTP protocol itself is stateless. What is stateless, that is, the server cannot determine the user’s identity. A cookie is actually a small piece of text information). The client sends a request to the server. If the server needs to record the user status, it uses response to issue a cookie to the client browser. The client browser saves the cookies. When the browser requests the website again, the browser submits the requested website address together with the cookie to the server. The server checks the cookie to identify user status.

For example, it’s like you have a bank card. Next time you go to the bank to do business, you can take the bank card directly. You don’t need an ID card.

2、 Try in. Net core

Without much nonsense, we are done. Now we create the asp.net core MVC project. We use the. Net core SDK 3.0 built project when we write this article. After the creation, we do not need to install any packages,

But we need to add some configuration in startup for cookie related.


//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>();
  }

In which we configure the login page, in which addauthentication is the name of our scheme. What is this for? Many little friends are ignorant, which means they are ignorant. I think many people write it by default, so what’s the use of it? After reading the source code of aspnetcore, I found that it can be configured. Look at the following 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);
 }

You can define some policies, and then you can directly change the variables of cookiescheme to replace some configurations. There are several items in the configuration, which is undoubtedly a good helper to help us use cookies quickly.

In the source code, you can see that the default time for cookies to be saved is 14 days. We can choose which types of timespan are supported.


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

Next, loginorout controller, we simulated Login and logout through signinasync and signoutasync methods.

[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 () =>
   {
    //Log off the logged in user, equivalent to formsauthentication.signout in asp.net 
    await HttpContext.SignOutAsync();
   }).Wait();
   return View();
  }

Take out the released source code, which obtains some information about the handler, and then converts it to the iauthenticationsignouthandler interface type. This interface as interface, like the local implementation of this interface, then passes some runtime value references to the interface.


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);
  }

In gethandlerasync, some instances are created according to the authentication policy. I won’t talk about it any more, because the source code is not deep enough, and I can’t say it clearly… I just want to express the advantages and disadvantages of the source 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;
  }

Finally, if we want to get the login information on the page, we can get it through the signature information in 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>

3、 Final effect and source address#

GitHub address: https://github.com/zaranetcore/aspnetcore’jsonwebtoken/tree/master/src/identity.cookie/dotnetcore’cookie’sample

summary

The above is the whole content of this article. I hope that the content of this article has some reference learning value for your study or work. Thank you for your support for developepaer.