- session 知识点
http协议是无状态的,所以我们连续访问100次和1次没有区别,都是没有记忆的。所以我们不能让用户每次访问网站都登陆一次,session 方案就被提出来了。
通过cookie和session为用户建立一次会话,在用户授权成功时给他一个cookie,是唯一的会话id。比如PHP就会为建立会话的用户默认设置一个名为phpsessid,cookie中存有phpsessid,返回给客户端,下次用户在请求的的时候带这个cookie,服务端就知道刚刚请求过了,不需要再登录了。
那么如何展示用户信息的,信息存在哪里呢?这时候可以用内存、也可以用文件,也可以用数据库,要求是数据需要用用户的会话id即可取到,比如php就默认会把会话id为abc的用户会话数据存储到/tmp/phpsess_abc【1】的文件里面,每次读取都要反序列化程序可以理解的数据,写的时候又需要序列化为持久的数据格式。
如何实现session 共享?
如果你的网站是存放在一个机器上,那么是不存在这个问题的,因为会话数据就在这台机器,但是如果你使用了负载均衡把请求分发到不同的机器呢?这个时候会话id在客户端是没有问题的,但是如果用户的两次请求到了两台不同的机器,而它的session数据可能存在其中一台机器,这个时候就会出现取不到session数据的情况,于是session的共享就成了一个问题。
事实上,各种web框架早已考虑到这个问题,比如asp.NET,是支持通过配置文件修改session的存储介质为sql server的,所有机器的会话数据都从同一个数据库读,就不会存在不一致的问题;php支持把会话数据存储到某台memcache服务器,你也可以手工把session文件存放的目录改为nfs网络文件系统,从而实现文件的跨机器共享。
还有一个简单的办法可以用于会话信息不会频繁变更的情况,在机器a设置用户会话的时候,把会话数据post到机器b的一个cgi,机器b的cgi把会话数据存下来,这样机器a和b都会有同一份session数据的拷贝
(sessionStorage ,在同一个会话中的页面才能访问,并且当会话结束后数据也随之销毁,因此 sessionStorage不是一种持久化的本地存储,仅、是会话级别的存储。只允许同一窗口访问
loacalStorage ,用于持久化的本地存储,除非主动删除数据,否则数据是永远不会过期的。同源可以读取并修改localStorage数据)
- token 鉴权和 session俩种方式的实现
token方式:
前几天研究了一下springboot security的一个项目,分析了源码,里面就是在使用token的登录验证机制,主要使用过程如上图,登录后根据security的安全算法生成一个唯一的token值(基于JWT),然后存储到redis中,并设定过期时间,之后把token值返回前台,前台保存到localStorage中,然后每次访问的时候都需要提交token作为验证,验证通过则可以访问接口。
session 方式: