背景
Web应用中,HTTP请求时无状态的,即:用户第一次发起请求,与服务器建立链接并登录成功后,为了避免每次打开一个页面都需要登录一下,就出现cookie、session.
Cookie
定义:Cookie是客户端保存用户信息的一种机制,用于存储 web 页面的用户信息。
Cookie作用
- 当用户访问 web 页面时,用户信息记录在 cookie 中。
- 在用户下一次访问该页面时,可以在 cookie 中读取用户访问记录。
存储容量
若一个域名下存储的数量大于当前的最大条数(chrome最大为180),浏览器将自动清除一些cookie
cookie运行机制
- 客户端发送一个请求到服务器
- 服务器发送一个HttpResponse响应到客户端,其中包含Set-Cookie的头部
- 客户端保存cookie,之后向服务器发送请求时,HttpRequest请求中会包含一个Cookie的头部
- 服务器返回响应数据
cookie属性项
- name&value:属性名和属性值cookie中的内容信息
- domain:设置cookie的作用范围
- path:指定一个URL路径,只有当路径匹配时,才会向服务器发送Cookie。
- Expires& Max-Age:设置cookie有效期,两者都存在时,Max-Age优先级更高。
- Secure:标记该属性的Cookie只应通过HTTPS协议加密过的请求发送给服务端。
- HttpOnly:防止跨站脚本攻击(XSS)
- Size与Priority:Cookie的大小一般为4KB,超出范围会移除旧的Cookie,移除时按照优先级由低到高删除。
- SameSite:让Cookie在跨站请求时不会被发送,可以阻止跨站请求伪造攻击(CSRF)
跨域携带cookie解决方案
- 通过CORS解决
- 服务器端配置:在服务器端设置响应头Access-Control-Allow-Credentials为true,并且Access-Control-Allow-Origin不能为*,必须是请求方的具体源
- 客户端配置:发起请求时,设置credentials为include确保请求会携带Cookie。
- 通过代码服务器解决
session
定义:session是另一种记录客户状态的机制
,是在服务端保存的一个数据结构(主要存储的是SessionID和Session内容
,同时包含了很多自定义的内容如:用户基础信息、权限信息、用户机构信息、固定变量等)
运行机制
- 用户第一次登录后,浏览器会将用户信息发送给服务器,服务器会为该用户创建一个SessionId,并在响应内容(Cookie)中将该SessionId一并返回给浏览器,浏览器将这些数据保存在本地。当用户再次发送请求时,浏览器会自动把上次请求存储的Cookie数据自动的携带给服务器。
- 服务器收到请求信息后,会通过浏览器请求的数据中的SessionId判断当前是哪个用户,然后根据SessionId在Session库中获取用户的Session数据返回给浏览器。
- Session生成后。只要用户继续访问,服务器就会更新Session的最后访问时间,并维护该Session。为防止内存溢出,服务器会把长时间内没有活跃的Session从内存删除。这个时间就是Session的超时时间。如果超过了超时时间没访问过服务器,Session就自动失效了,用户需要重新登录。
Token
出现的背景
Http请求是以无状态的形式对接(http服务器不知道本次请求和上一次请求是否有关联。所以就有了Session的引入,即服务端和客户端都保存一段文本,客户端每次发起请求都带着,这样服务器就知道客户端是否发起过请求。但是Session的存储是需要空间的,频繁的查询数据库给服务器造成很大的压力。)
Token运行机制
Token是服务端生成的一串字符串,以作客户端进行请求的一个令牌。当客户端第一次访问服务端,服务端会根据传过来的唯一标识userId,运用有些算法,并加密,生成一个token,然后通过BASE64编码一下之后将这个token返回给客户端,客户端将token保存。下次请求时,客户端只需要带上token,服务器收到请求后,会用相同的算法和密钥去验证token。
token流程
- 客户端使用用户名跟密码请求登录
- 服务端收到请求,去验证用户名与密码
- 验证成功后,服务端会签发一个Token,并设置一个有效期。再把这个token发送给客户端
- 客户端收到token后把它存储起来,放在cookie或数据库里
- 客户端每次向服务端请求资源时需要带着服务端签发的token
- 服务端收到请求,然后验证客户端请求带着的token。验证成功,就向客户端返回请求的数据。
token应该存在Cookie、SessionStorage、LocalStorage中?
- Cookie:token存储在cookie中,
优点
是:可以保持登录状态,即使浏览器关闭,cookie仍然存在。缺点
:容易收到CSRF(跨站请求伪造)攻击。 - SessionStorage:
优点
:只存在当前会话中,用户关闭浏览器后,sessionStorage中的数据将被清除。缺点
:用户在浏览器中打开新的标签页或窗口时,新页面将无法访问sessionStorage的数据 - LocalStorage:
优点
:浏览器关闭后,localStorage中的数据依然存在,用户保持登录状态。数据可以在统一浏览器的所有标签页和窗口中共享。缺点
:容易受XSS(跨站脚本)攻击
token存储位置取决于应用需求。
cookie中的token如何避免CSRF攻击?
- 使用SameSite属性:SameSite属性可以设置Strict、Lax、None。设置为Strict时,cookie只会在同源请求中发送。设置为Lax时,cookie会在同源请求和顶级导航中发送。设置为None时,cookie会在所有请求中发送
- 使用CSRF Token:在每个请求中添加一个随机生成的CSRF Token,服务器验证这个token。不匹配,请求将拒绝。
- 使用Refer Header:服务器端检查Referer Header,请求不是来自同一源,请求将拒绝。
LocalStorage中的token,如何避免XSS攻击?
- 使用Content Security Policy(CSP):CSP可以限制浏览器只加载和执行来自特定源的脚本,防止XSS攻击。
- 对用户输入进行验证和转义:对所有用户输入进行验证,特殊字符进行转义,防止恶意脚本被执行。
- 使用HttpOnly属性:token存储在HttpOnly的cookie中,服务器端验证token。
cookie 、localStorage、sessionStorag的区别
localStorage
- localStorage.setItem(key,value):将value存储到key字段
- localStorage.getItem(key):获取指定key本地存储的值
localStorage存储的最大容量为5M,若存储容量溢出,怎么办?
- 首先浏览器会报一个名为“QuotaExceededError”的错误
如何解决?
-
跨页面传数据:考虑单页应用、优先采用URL传数据
-
同一个域名下的,清掉别人的存储。不同域名下,统一规划
cookie和session的区别?
- 存在的位置:
cookie存在于客户端,临时文件夹中。
session存在于服务器的内存中,一个session域对象为一个用户浏览器服务
- 安全性
cookie是以明文的方式存放在客户端的,安全性低。可以通过一个加密算法进行加密后存放。
session存放在服务器的内存中,安全性好。
- 网络传输量
cookie会传递消息给服务器
session本身存放于服务器中,不会有传送流量
- 访问范围
cookie为多个用户浏览器共享
session为一个用户浏览器独享。
跨域请求携带cookie问题?
-
前端请求时在request对象中配置withCredentials:true,
-
服务端在response的header中配置Access-Control-Allow-Origin,“[http://xxx:%7Bport%7D")`
-
服务端在response的header中配置Access-Control-Allow-Credentials,true
浏览器关闭状态
- cookie的值还是存在的,前提是设置的cookie过期时间
- localStorage的值还是存在的,除非主动删除数据
- sessionStorage数据,浏览器关闭自动删除