1. http协议是无状态的协议
- Http是一个无状态的协议,每一次请求是独立无关联的,服务器是无法识别两次请求是不是同一个客户发送的,比如访问个人博客网站,肯定要登录,那么浏览器端向服务器端发送http请求,并带上账号和密码信息,服务器端对账号密码进行验证,响应给客户端,假如客户端收到登录成功的信息,说明此刻登录完成了,客户进入个人中心页面,又需要向服务器请求个人中心的数据,由于HTTP请求属于是无状态的,第一次请求和第二次请求没有联系,那么服务器端根本就不知道用户是否已经登录了,那更别提怎么返回特定用户对应的个人中心界面的信息了。所以说这是cookie和session诞生的一个前提
2. cookie
- 什么是cookie,是服务器发送到用户浏览器并保存在本地的一小块数据,它会在浏览器下次向同一服务器再发起请求时被携带并发送到服务器上,主要用于管理会话状态,进行个性化设置和浏览器用户跟踪(比如脸书在谷歌浏览器插入的广告)
浏览器加载下面代码时,就会向 Facebook 发出带有 Cookie 的请求,从而 Facebook 就会知道你是谁,访问了什么网站。Cookie 的SameSite属性用来限制第三方 Cookie(广告商往往就是第三方cookie),从而减少安全风险。
<img src="facebook.com" style="visibility:hidden;">
- 每次请求都会自动带上相同域名下的cookie,所以会增加网络开销,所以尽量只在cookie里存每次请求必须要携带的信息(比如身份认证信息等等),其他的尽量存在sessionStorage或者localStorage里面
- cookie不安全,由于cookie存储在客户端里,所以非常的不安全,我们在调试台的application里可以清清楚楚的看cookie存储的内容,并且可以修改,所以可以在存储cookie的时候对其进行加密,获取cookie的时候对其进行解密,要是解密后解出来不对,就说明已经被篡改了(服务端存储cookie的时候加密,客户端下次请求带上了cookie,服务器对这个cookie进行解密)
- cookie分为持久性cookie和会话性cookie
对于会话性cookie,把cookie存储在内存中,一旦关闭浏览器,cookie就会消失;对于持久性cookie,服务器端在set-cookie字段里,会给cookie设置一个过期时间,浏览器拿到响应的数据后会存储到磁盘里面,所以即使关闭浏览器,cookie也不会消失,直到到达过期的时间,这样就可以实现一些七天免登录的功能。服务器端可以创建,读取,修改,删除cookie(max-age<0即可)
(1)path:设置cookie的作用路径,默认值为设置该cookie的网页所在的目录。比如Path=/docs,/docs/Web/ 下的资源会带 Cookie 首部,/test 则不会携带 Cookie 首部 (2)domain:默认为请求访问的地址中的主机部分(不包含子域名),对于跨域访问,如域A为t1.study.com,域B为t2.study.com,那么在域A生产一个令域A和域B都能访问的cookie就要将该cookie的domain设置为.study.com(需要带点) Domain 和 Path 标识共同定义了 Cookie 的作用域:即 Cookie 应该发送给哪些 URL。
合适的做法就是,服务器第一次验证账号登录的时候,返回响应报文的时候,在响应头里面加上set-cookie字段,设置一个cookie,里面存储对应的用户信息,浏览器收到响应后保存下cookie,之后对该服务器的每一次请求都可以通过cookie字段将cookie信息(携带一段用户信息),后台检测到这段用户信息之后,就判定为已经登陆了
3. session
那么除了把特定的用户信息存储在客户端,也可以存储在服务端
- Session 是存储在服务器端的,在服务端保存Session的方法很多,内存、数据库、文件都可以,服务器会为特定的用户创建特定的session,用于标识跟踪用户,Session有一个唯一标识sessionId
- session的运行原理
- 利用cookie来实现session跟踪
- 刚刚的登录场景如果用session来实现的话,是这样一个流程:
- 用户提交包含用户名和密码的表单,发送HTTP请求
- 服务器验证账号密码,如果正确就把当前用户信息对象存储到session中(可以是通过redis保存的),并生成在session对应的Session ID,并把这个Session ID通过响应报文的set-cookie字段返回给浏览器
- 下一次浏览器端再发送请求的时候,就会带上包含Session ID的cookie,服务器端通过Session ID可以从redis找到对应是session,判断里面是否有用户信息,如果存在,就说明用户之前登陆过,如果给sessionId设置过期时间为七天,也可以设置七天免登录
- session的过期时间,是通过给sessionI设置过期时间来达到的
4. cookie和session的区别
- 一个存储在浏览器,一颗存储在服务器,session相比于cookie来说更安全,不像cookie随时都可以被别人篡改和查看
- cookie只能存字符串类型,想要存储其他类型的数据需要先转化为字符串,session可以存储任意数据类型
- 有效期不同,cookie可以设置有效期,并且可以设置为持久性cookie,长时间地进行存储(比如qq的默认登录功能),但是session一般失效事件较短,默认情况下客户端关闭(sessionId没了,session就会失效)或者session超时都会失效
- 存储大小不同,cookie保存的数据大小<=4kb,个数<=20,session可存储数据远远高于cookie,但是访问量过多时,会占有更多的服务器资源,很多人登录的时候服务器会存储很多很多的服务器资源(可以不存在内存里,存在redis里)
Session是在服务端保存的一个数据结构,用来跟踪用户的状态,这个数据可以保存在集群、数据库、文件中; Cookie是客户端保存用户信息的一种机制,用来记录用户的一些信息,也是Session的一种实现机制。
还有一个例子就是:比如有些网站有一个首次免费试用的活动,但是用了一次之后,就需要登录付费,就是利用了cookie和session的机制,服务器是给浏览器打上了cookie,并且在后台设置了session来记录你的状态,浏览器每次访问该网站的时候都会带上cookie,服务器一查session就知道这个浏览器已经免费使用过了,就必须要登录付费了
5. cookie的跨域问题
ajax是不会携带非同源的cookie的,(端口号8080向端口号3000的服务器发送http请求的时候,3000的set-cookie字段8080客户端是接收不到的),可以使用反向代理或者token,或者cors解决
|