目录
六、WebStorage(包括localStorage和sessionStorage)
4.3 localStorage和sessionStorage的特点
一、Cookie
1.1 为什么有cookie和seesion?(http请求是无状态的)
客户端 请求 服务器, 属于HTTP请求。http请求是无状态的,即每次服务端接收到客户端的请求时,都是一个全新的请求,服务器并不知道客户端的历史请求记录;所以当用户从客户端请求一次登录后,登录成功,再次进行请求时,因为服务器不能识别这两次会话都是来自同一个浏览器,即服务端不知道客户端的历史请求记录;就会再次弹出登录对话框。
为了解决客户端与服务端会话同步问题。这便引出了:cookie、session,用来跟踪浏览器用户身份的会话方式
cookie分为会话cookie 和 持久cookie:
会话cookie: 浏览器关闭,销毁
持久cookie:设定了它的生命周期expires,直到时间到期,信息销毁(即便你关闭了浏览器,再次开启浏览器,依然存在)。
session:
1.2 cookie的工作原理?
Cookie实际上是一小段的文本信息。
(1)浏览器端第一次发送请求到服务器端;
(2)如果服务器需要记录该用户状态,服务器端就创建Cookie,该Cookie中包含用户的信息,然后将该Cookie发送到浏览器端;
(3)浏览器端再次访问服务器端时,会携带服务器端创建的Cookie;
(4)服务器端通过Cookie中携带的数据,区分不同的用户(服务器还可以根据需要修改Cookie的内容);
实际就是颁发一个通行证,每人一个,无论谁访问都必须携带自己通行证。这样服务器就能从通行证上确认客户身份了。这就是Cookie的工作原理。
1.3 cookie的属性:domain
设置可以访问该Cookie的域名。如果设置为“.google.com”,则所有以“google.com”结尾的域名都可以访问该Cookie。注意第一个字符必须为“.”。
总结:
- domain表示的是cookie所在的域,默认为请求的地址,如网址为www.study.com/study,那么domain默认为www.study.com。
- 而跨域访问,如域A为t1.study.com,域B为t2.study.com,那么在域A生产一个令域A和域B都能访问的cookie就要将该cookie的domain设置为.study.com;如果要在域A生产一个令域A不能访问而域B能访问的cookie就要将该cookie的domain设置为t2.study.com。注意:一般在域名前是需要加一个"."的,如"domain=.study.com"。
1.4 cookie的HttpOnly属性
如果set-cookie中设置了HttpOnly属性,那么通过js脚本将无法读取到cookie信息。这样能有效的防止XSS攻击,窃取cookie内容,增加了cookie的安全性 。
response.setHeader("Set-Cookie",HTTPOnly;Domain=domainvalue;Max-Age=seconds");
1.5 cookie的SameSite 属性
1) 该属性用来限制第三方 Cookie,从而减少安全风险。该属性有三个值可选:
- Strict:完全禁止第三方 Cookie,跨站点时,任何情况下都不会发送 Cookie。换言之,只有当前网页的 URL 与请求目标一致,才会带上 Cookie。
- Lax:大多数情况也是禁止发送第三方 Cookie,但是导航到目标网址的 Get 请求除外。导航到目标网址的 GET 请求,只包括三种情况:链接,预加载请求,GET 表单。详见下表。
请求类型 | 示例 | 正常情况 | Lax |
---|---|---|---|
连接 | <a href="..."></a> | 发送 Cookie | 发送 Cookie |
预加载 | <link rel="prerender" href="..."/> | 发送 Cookie | 发送 Cookie |
GET 表单 | <form method="GET" action="..."> | 发送 Cookie | 发送 Cookie |
POST 表单 | <form method="POST" action="..."> | 发送 Cookie | 不发送 |
- None:关闭SameSite属性。设置该属性的前提是必须同时设置Secure属性(Cookie 只能通过 HTTPS 协议发送),否则无效。
设置了Strict或Lax以后,基本就杜绝了 CSRF 攻击。当然,前提是用户浏览器支持 SameSite 属性。
2)怎样才算第三方请求?
当一个请求本身的 URL 和它的发起页面的 URL 不属于同一个站点时,这个请求就算第三方请求。那么怎样算是同一个站点?不是我们经常说的同源(same-origin)。a.com 和 a.com:8000 是不同源的,但它俩绝对是属于同一个站点的,浏览器在判断第三方请求时用的判断逻辑并不是同源策略,而是用了 Public Suffix List 来判断。
参考:Cookie 的 SameSite 属性_alone-CSDN博客_samesite
1.6 设置cookie的过期时间
可通过两个属性设置:
- Expires(HTTP/1.0):指定一个绝对的过期时间。出现的问题:客户端和服务器时间不同步导致Expires的配置出现问题;很容易在配置后忘记具体的过期时间;
- Cache-Control:max-age (HTTP/1.1):max-age 指定的是从文档被访问后的存活时间,是个相对值。
- cookie.setMaxAge(0);//不记录cookie
- cookie.setMaxAge(-1);//会话级cookie,关闭浏览器失效
- cookie.setMaxAge(60*60);//过期时间为1小时(单位为s)
1.7 cookie的api
1.Cookie cookie = new Cookie(“key”,“value”) 创建cookie
response.addCookie(cookie) 必须要add才能生效
2.request.getCookies() 读取cookie
3.void setMaxAge(int age) 设置cookie有效时间,单位为秒
4.void getMaxAge() 获取cookie的有效时间
5.cookie.getName():得到此cookie对象的名字
6.cookie.getValue(String name):得到对应名称的cookie的值
1.8 cookie面临的问题
- Cookie只能保存少量的数据。每个domain(特点的域名下)最多只能有20条cookie,每个cookie长度不能超过4kb,否则会被截掉;
- 安全性问题。如果cookie被人拦截了,那人就可以取得所有的session信息。即使加密也于事无补,因为拦截者并不需要知道cookie的意义,他只要原样转发cookie就可以达到目的了。
- 有些状态不可能保存在客户端。例如,为了防止重复提交表单,我们需要在服务器端保存一个计数器。如果我们把这个计数器保存在客户端,那么他起不到任何作用。
- 每次客户端的访问都必须传回这些Cookie,如果 Cookie 很多,这无形地增加了客户端与服务端的数据传输量(通过session解决)
二、Session
2.1 什么是session?
而 Session 的出现正是为了解决cookie中的安全性问题、数据传输量大的问题。
同一个客户端每次和服务端交互时,不需要每次都传回所有的 Cookie 值,而是只要传回一个 ID,这个 ID 是客户端第一次访问服务器的时候生成的, 而且每个客户端是唯一的。这样每个客户端就有了一个唯一的 ID,客户端只要传回这个 ID 就行了,这个 ID 通常是 NANE 为JSESIONID 的一个 Cookie(例:响应头Set-Cookie:“JSESSIONID=服务端生成的ID”)。
2.2 session的工作原理?
(1)服务器第一次接收到请求时,开辟了一块Session空间(创建了Session对象,将用户信息储存到服务器的Session中),同时生成一个Session id;
(2)通过响应头的Set-Cookie:“JSESSIONID=Session id”命令,通过响应头将该Cookie发送至客户端;
(3)客户端收到响应后,在本机客户端设置了一个JSESSIONID=Session id的cookie信息;
(4)接下来客户端每次向同一个网站发送请求时,请求头都会带上该cookie信息(包含Session id);
(5)然后,服务器通过读取请求头中的Cookie信息,获取名称为JSESSIONID的值,得到此次请求的Session id,从而找到对应的用户信息;
注意:服务器只会在客户端第一次请求响应的时候,在响应头上添加Set-Cookie:“JSESSIONID=XXXXXXX”信息,接下来在同一个会话的第二第三次响应头里,是不会添加Set- Cookie:“JSESSIONID=XXXXXXX”信息的; 而客户端是会在每次请求头的cookie中带上JSESSIONID信息;
2.3 session的缺点?
- 一般是寄生在Cookie下的,当Cookie被禁止,Session也被禁止。
- 当用户访问量很大时,对服务器压力大。session是将用户信息储存在服务器上面,如果访问服务器的用户越来越多,那么服务器上面的session也越来越多, session会对服务器造成压力
三、Cookie与Session的区别
区别 | Cookie | Session |
---|---|---|
存在 | 保存在客户端,不是十分安全 | 在服务端 |
存储数据 | String 类型。如果我们存储一个对象,这个时候,就需要将对象转换为JSON | 对象类型 |
存储的数据大小 | 最大为4k | 受服务器内存控制 |
有效时间 | 当浏览器关闭,cookie也就消失了。Cookie可以通过 setMaxAge设置有效时间,即使浏览器关闭了仍然存在 | 关闭网页Session就结束了 |
作用域 | Cookie通过设置domian指定作用域,只能在指定作用域有效 | Session在整个网页都有效 |
性能 | Cookie存在客户端对服务器没影响 | Session过多时会消耗服务器资源,大型网站会有专门Session服务器 |
- cookie数据存放在客户的浏览器上,session数据放在服务器上
- cookie不是很安全,别人可以分析存放在本地的COOKIE并进行COOKIE欺骗,如果主要考虑到安全应当使用session
- session会在一定时间内保存在服务器上。当访问增多,会比较占用你服务器的性能,如果主要考虑到减轻服务器性能方面,应当使用COOKIE
- 单个cookie在客户端的限制是4K,就是说一个站点在客户端存放的COOKIE不能4K。
- 所以:将登陆信息等重要信息存放为SESSION;其他信息如果需要保留,可以放在COOKIE中
参考博客:https://blog.csdn.net/chen13333336677/article/details/100939030
四、token
token产生的原因:
- Seesion:每次认证用户发起请求时,服务器需要去创建一个记录来存储信息。当越来越多的用户发请求时,内存的开销也会不断增加。
- CSRF(跨站请求伪造):用户在访问银行网站时,他们很容易受到跨站请求伪造的攻击,并且能够被利用其访问其他的网站。
- CORS(跨域资源共享):当我们需要让数据跨多台移动设备上使用时,跨域资源的共享会是一个让人头疼的问题。在使用Ajax抓取另一个域的资源,就可以会出现禁止请求的情况。
基于Token的身份验证是无状态的,我们不将用户信息存在服务器或Session中。
Token 是在服务端产生的一串字符串。如果前端使用用户名/密码向服务端请求认证,服务端认证成功,那么在服务端会返回 Token 给前端。前端可以在每次请求的时候带上 Token 证明自己的合法地位。
基于 Token 的身份验证,在服务端不需要存储用户的登录记录:
- 客户端使用用户名和密码请求登录
- 服务端收到请求,去验证用户名与密码。
- 验证成功后,服务端以某种方式比如随机生成32位的字符串作为token,存储到服务器中(可存到session),并把这个 Token 发送给客户端。
- 客户端收到 Token 以后可以把它存储起来,比如放在 Cookie 里或者 Local Storage 里。
- 客户端每次向服务端请求资源的时候需要带着服务端签发的 Token
- 服务端收到请求,然后去验证客户端请求里面带着的 Token。如果验证成功,就向客户端返回请求的数据;失败返回错误信息,让他重新登录。
其中服务器上token设置一个有效期,每次APP请求的时候都验证token和有效期。
根据系统的安全需要,有效期尽可能的短。
token的产生:服务端会根据用户id
、用户名、定义好的秘钥、过期时间生成一个 Token。
五、JWT(JSON Web Token)
1)token与jwt的相同与区别:
- 相同: 都是访问资源的令牌, 都是只有验证成功后可以记录用户信息;
- 不同: 对于token,服务端验证客户端发来的token信息,要进行数据的查询操作;JWT直接在服务端使用密钥,校验验证客户端发来的token信息就可以,不用数据库的查询。
2)什么情况下用JWT?
- 授权:这是最常见的使用场景,解决单点登录问题。因为JWT使用起来轻便,开销小,服务端不用记录用户状态信息(无状态),并且可以跨域使用。一旦用户登录,后续每个请求都将包含JWT;
- 信息交换:JWT是在各个服务之间安全传输信息的好方法。因为JWT可以签名,例如,使用公钥/私钥对儿 - 可以确定请求方是合法的。此外,由于使用标头和有效负载计算签名,还可以验证内容是否未被篡改。
3)JWT token的组成?
- Header/头部:包含token的类型(JWT) 和 签名时使用的算法(散列算法);
- Payload/载荷:存储使用的数据;
- Signature/签名:创建签名部分。使用编码后的Header+ 编码后的Payload+ Header中指定的算法+秘钥,对其进行签名。签名用于验证消息在此过程中未被篡改,并且,在使用私钥签名令牌的情况下,它还可以验证JWT的请求方是否是合法的请求方。
HMACSHA256(
base64UrlEncode(header) + "." +
base64UrlEncode(payload),
secret)
4)jwt的工作机制
- 当用户成功登录时,服务器端生成一个JWT返回给客户端;
- 客户端每次请求时,带上该JWT(通常在Authorization header中),服务器端只需要对该JWT进行解密,就可以得知该JWT是否有效、用户的信息(注意不能有敏感信息)等;
- 如果有效,则允许用户访问受保护资源;
- 这个过程服务端不需要存储JWT的内容(不同于之前类似Session id的那种token),只需要对JWT进行加解密操作;
- 由于令牌是凭证,因此必须非常小心以防止出现安全问题。一般情况下,不应将令牌保留的时间超过要求。理论上超时时间越短越好。
- 如果在Authorization header中发送令牌,则跨域资源共享(CORS)将不会成为问题,因为它不使用cookie。
六、WebStorage(包括localStorage和sessionStorage)
webstorage是本地存储,存储在客户端,包括永久性的本地存储localStorage和会话级别的本地存储sessionStorage。
这两本质上的区别就是,当你关闭窗口后,sessionStorage里面的存储的数据将全部清空
4.1 localStorage
- 为永久保存,将数据保存在客户端本地的硬件设备(通常指硬盘,也可以是其他硬件设备)中,即使浏览器被关闭了,该数据仍然存在,除非removeItem;
- 存放数据大小为一般为5MB,而且它仅在客户端(即浏览器)中保存,不参与 和服务器的通信;
- 取代了globalStorage(globalStorage必须指定域名);
- Storage类型的一个对象;
localStorage 的api:
// 新建一对key-value到localStorge
localStorge.setItem("key", "value");
// 从localStorge通过key获取value
var value = localStorge.getItem("key");
localStorage.removeItem(k):删除键值为k的变量。
localStorage.clear():清空所有变量。
localStorage.length;
4.2 sessionStorage
- 为临时保存,仅在当前会话下有效,关闭页面或浏览器后被清除;
- 存放数据大小为一般为5MB,而且它仅在客户端(即浏览器)中保存,不参与 和服务器的通信;
- Storage类型的一个对象;
4.3 localStorage和sessionStorage的特点
1)存储大小:
localStorage和sessionStorage的存储数据大小一般都是:5MB
2)存储位置:
localStorage和sessionStorage都保存在客户端,不与服务器进行交互通信
3)应用场景:
localStoragese:常用于长期登录(+判断用户是否已登录),适合长期保存在本地的数据,而sessionStorage:敏感账号一次性登录
4)获取方式:
localStorage:window.localStorage;;sessionStorage:window.sessionStorage;
sessionStorage只有同源同窗口中共享,只要浏览器不关闭,数据仍然存在
4.4 sessionStorage、localStorage和cookie的区别
- 相同点是都是保存在浏览器端、且同源的;
- cookie数据始终在同源的http请求中携带(即使不需要),即cookie在浏览器和服务器间来回传递,而sessionStorage和localStorage不会自动把数据发送给服务器,仅在本地保存;
- cookie数据还有路径(path)的概念,可以限制cookie只属于某个路径下;
- 存储大小限制也不同,cookie数据不能超过4K,由于每次http请求都会携带cookie,cookie只适合保存很小的数据(如会话标识)。sessionStorage和localStorage虽然也有存储大小的限制,但比cookie大得多,可以达到5M或更大;
- 数据有效期不同,sessionStorage:仅在当前浏览器窗口关闭之前有效;localStorage:始终有效,窗口或浏览器关闭也一直保存,因此用作持久数据;cookie:只在设置的cookie过期时间之前有效,即使窗口关闭或浏览器关闭;
- 作用域不同,sessionStorage只有同源同窗口中共享;localstorage在所有同源窗口中都是共享的;cookie也是在所有同源窗口中都是共享的
- web Storage支持事件通知机制,可以将数据更新的通知发送给监听者
- web Storage的api接口使用更方便
4.5 WebStorage的优点
- 存储空间更大:cookie为4KB,而WebStorage是5MB
- 节省网络流量:WebStorage不会传送到服务器,存储在本地的数据可以直接获取,减少了客户端和服务器端的交互,节省了网络流量
- 对于那种只需要在用户浏览一组页面期间保存而关闭浏览器后就可以丢弃的数据,sessionStorage会非常方便
- 快速显示:有的数据存储在WebStorage上,获取数据时可以从本地获取会比从服务器端获取快得多,所以速度更快
- 安全性:WebStorage不会随着HTTP header发送到服务器端,所以安全性相对于cookie来说比较高一些,不会担心截获,但是仍然存在伪造问题
- WebStorage提供了一些方法,数据操作比cookie方便
- setItem (key, value) —— 保存数据,以键值对的方式储存信息。
- getItem (key) —— 获取数据,将键值传入,即可获取到对应的value值。
- removeItem (key) —— 删除单个数据,根据键值移除对应的信息。
- clear () —— 删除所有的数据
- key (index) —— 获取某个索引的key
可参考cookie、sessionStorage和localStorage的区别:
cookie、sessionStorage和localStorage的区别_浮生离梦的博客-CSDN博客
五、作用域
1)localStorage只要在相同的协议、相同的主机名、相同的端口下,就能读取/修改到同一份localStorage数据,即在所有同源窗口中都是共享的
2)sessionStorage比localStorage更严苛一点,除了协议、主机名、端口外,还要求在同一窗口(也就是浏览器的标签页)下。
3)cookie在所有同源窗口中都是共享的
六、怎么设计登录,token呢?讲一讲 JWT?