3分钟快速学会在ASP.NET Core MVC中如何使用Cookie

2020-01-18 19:39:05丽君


在源码中可以看到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;
  }