什么是Session

http是无状态的,就是每个请求都是独立的,上一个请求是用户登录,本来用户已经登录了,下一个请求显示登录后的主页,由于http无状态,显示主页这个请求根本不知道用户登录了。

Session就可以用来记录登录这种状态,在用户登录的时候,就给这个用户创建一个session,这个session里面保存一些自定义配置,用户信息等。Session是存在于服务器的内存中,当然可以存在文件,或者数据库里面,创建的时候还可以设置session的过期时间。到期了session就被销毁了。

Session存放位置

Session一般创建的时候是存在服务的内存中,到期自动销毁。
但是有个弊端。
用户多了,创建大量的Session,内存???

所以有了Session持久化一说,把Session存在文件里面。或者数据库里面。随便存,当我硬盘和内存一样小啊。
但是吧,如果要频繁访问Session,你频繁的读取文件或者数据库,也不太合适吧,而且过期了不能自动删除。

但是想要删除保存在文件或者数据库中的session也不是不可以,它不能自行判断过期时间自动删除,比如,你可以在用户登录的时候创建这个用户的session,然后进行遍历所有的文件或者数据库里面的session。过期的删掉。
性能不佳啊,曲线救国嘛。

怎么匹配Session是那个用户的

在创建session时,会创建一个sessionid,这个sessionid放在cookie里面。随着响应头,把这个cookie一起发给客户端。响应成功后,这个客户端的浏览器就收到了这个cookie。之后每次发送请求,都会自动加上这个cookie一起发给后端。
如果要查询session里面的值,会自动匹配这个请求头里面的cookie里面的sessionid,匹配到了,就给相应的session。
没有sessionid匹配?哪怕服务器内存中的session没有过期?
服务器:对不起没有sessionid,我不认!

使用

打开项目的依赖项,看框架,只有AspNetCore.App才能使用这个session,cookie 单独创建的类库,依赖项的框架里面只有 NetCore.App,不能像下面这样使用session,cookie 需要在类库里面安装两个包, AspNetCore.Http和AspNetCore.Session

先注册服务

  1. services.AddDistributedMemoryCache();
  2. services.AddSession(options =>
  3. {
  4. //设置过期时间,单位秒,也可以设置分钟
  5. //指的是在这个时间内,对session没有任何操作(包括查询设置),session就自动过期了
  6. options.IdleTimeout = TimeSpan.FromSeconds(10);
  7. options.Cookie.HttpOnly = true;是否可以通过客户端脚本访问cookie
  8. });
  9. //用这个来操作cookie,session
  10. services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();

然后使用中间件,注意使用顺序,在路由后面,

  1. app.UseRouting();
  2. //配置Cors
  3. app.UseCors("a");
  4. app.UseAuthorization();
  5. app.UseSession();//使用Session中间件
  6. app.UseEndpoints(endpoints =>
  7. {
  8. endpoints.MapControllers();
  9. });

然后在控制器的构造方法中注入服务

  1. private Users user;
  2. private Blog6Context db;
  3. private IHttpContextAccessor accessor;
  4. private ISession session;
  5. public UsersController(Users u,Blog6Context b, IHttpContextAccessor h)
  6. {
  7. user = u;
  8. db = b;
  9. accessor = h;
  10. session = h.HttpContext.Session;
  11. }

最后就可以使用session了

  1. session.SetString("qq", "123456");//设置session

指向同一个session

前端axios发送请求时,只要涉及到session,发送的请求都要设置withCredentials: true

  1. this.$http({
  2. method:"post",
  3. url:this.url+"/api/users/login",
  4. data:user,
  5. withCredentials: true
  6. })

SessionHelper

  1. using Microsoft.AspNetCore.Http;
  2. using Newtonsoft.Json;
  3. using System;
  4. using System.Collections.Generic;
  5. using System.Linq;
  6. using System.Threading.Tasks;
  7. namespace BookApi.CookieSession
  8. {
  9. /// <summary>
  10. /// Session操作类
  11. /// </summary>
  12. public class SessionHelper
  13. {
  14. private readonly IHttpContextAccessor httpContextAccessor_;
  15. public SessionHelper(IHttpContextAccessor httpContextAccessor)
  16. {
  17. httpContextAccessor_ = httpContextAccessor;
  18. }
  19. /// <summary>
  20. /// 新增复杂型session
  21. /// </summary>
  22. /// <typeparam name="T"></typeparam>
  23. /// <param name="key"></param>
  24. /// <param name="value"></param>
  25. public void SetObject<T>(string key, T value)
  26. {
  27. httpContextAccessor_.HttpContext.Session.SetString(key, JsonConvert.SerializeObject(value));
  28. }
  29. /// <summary>
  30. /// 获取复杂型session
  31. /// </summary>
  32. /// <typeparam name="T"></typeparam>
  33. /// <param name="key"></param>
  34. /// <returns></returns>
  35. public T GetObject<T>(string key)
  36. {
  37. var value = httpContextAccessor_.HttpContext.Session.GetString(key);
  38. return value == null ? default(T) : JsonConvert.DeserializeObject<T>(value);
  39. }
  40. /// <summary>
  41. /// 添加Session
  42. /// </summary>
  43. /// <param name="strSessionName">Session键</param>
  44. /// <param name="strValue">Session值</param>
  45. public void Add(string strSessionName, string strValue)
  46. {
  47. httpContextAccessor_.HttpContext.Session.SetString(strSessionName, strValue);
  48. }
  49. /// <summary>
  50. /// 读取某个Session对象值
  51. /// </summary>
  52. /// <param name="strSessionName">Session键</param>
  53. /// <returns>Session对象值</returns>
  54. public object Get(string strSessionName)
  55. {
  56. if (httpContextAccessor_.HttpContext.Session == null
  57. || httpContextAccessor_.HttpContext.Session.GetString(strSessionName) == null)
  58. {
  59. return null;
  60. }
  61. else
  62. {
  63. return httpContextAccessor_.HttpContext.Session.GetString(strSessionName);
  64. }
  65. }
  66. /// <summary>
  67. /// 修改Session
  68. /// </summary>
  69. /// <param name="strSessionName"></param>
  70. /// <param name="objVal"></param>
  71. public void Update(string strSessionName, string objVal)
  72. {
  73. object obj = Get(strSessionName);
  74. if (obj != null)
  75. {
  76. Del(strSessionName);
  77. }
  78. Add(strSessionName, objVal);
  79. }
  80. /// <summary>
  81. /// 删除某个Session对象
  82. /// </summary>
  83. /// <param name="strSessionName">Session对象名称</param>
  84. public void Del(string strSessionName)
  85. {
  86. httpContextAccessor_.HttpContext.Session.Remove(strSessionName);
  87. }
  88. }
  89. }

参考

session默认有效期多长_Session和Cookie的关系