概述
文章目录
- 浏览器本地缓存 localstorage/sessionstorage/cookie
- 面试题
- cookie
- cookie的sameSite属性
- cookie如何跨域
- sameSite
- sameParty 首选
- 三者的区别
- localstorage的定时删除 --重写localstorage方法
- token
- 面试题
- token是什么
- token的认证过程
- cookie和token的区别,为什么选cookie/token
- token存储在本地的哪里?Refresh Token
- 身份认证 session机制和JWT机制
- 面试题
- session方案 cookie+session
- 常用场景
- JWT方案
- token和JWT
- 如何选择JWT方案和session方案
浏览器本地缓存 localstorage/sessionstorage/cookie
参考:https://juejin.cn/post/7087206796351242248
HTTP 是无状态的协议,每个请求都是完全独立的,服务端无法确认当前访问者的身份信息,无法分辨上一次的请求发送者和这一次的发送者是不是同一个人。所以服务器与浏览器为了进行会话跟踪(知道是谁在访问我),就必须主动的去维护一个状态,这个状态用于告知服务端前后两个请求是否来自同一浏览器。而这个状态需要通过 cookie 或者 session 去实现。
面试题
- cookie的HttpOnly的作用?
- 三者的区别?
- 怎么设置localstorage 过期时间 自动删除它
- cookie 哪些字段 怎么设置cookie,samesite了解嘛?
- 什么场景需要删除localstorage里的数据
- 两个页面之间怎么传参
- cookie在浏览器中的存储是什么样子的
- 请求默认会携带cookie么?
- 如何配置跨域允许携带cookie?子域也能携带cookie吗?
- 原生js获取cookie是如何获取的?
- localStorage存储的信息能窃取到吗?
- 开了两个完全一样的页面,cookie、localstorage、sessionstorage哪个能访问?
- 设置cookie的过期时间是由前端设置的吗?
- cookie是什么格式-字符串
- 说一下跨域请求如何携带cookie?
cookie
cookie的特点
- cookie是不可跨域的,每个cookie都会绑定单一的域名,无法在别的域名下获取使用
- cookie 是服务器发送到用户浏览器并保存在本地不超过4K的数据,当用户端发起请求时,会自动把当前域名下所有未过期的Cookie一同发送给服务器
会限制第三方cookie的携带。
什么是第三方cookie
第三方cookie指非同站(顶级域名+二级域名同),比如ai.taobao.com
和www.taobao.com
是同站的,domain一列中显示和当前域名不同站的就是三方cookie。
1.可以忽略协议和端口共享
http:// www.baidu.com:8080
与https:// www.baidu.com:9090
是可以共享cookie
2.顶级域名+二级域名相同可以共享
https:// running.aaa.com.cn
与https:// slave.aaa.com.cn
是可以共享cookie
cookie的主要属性
属性 | 说明 |
---|---|
domain | 默认是当前域名,请求哪些域名才会被携带 |
maxAge | cookie 失效的时间,单位秒。 如果为正数,则该 cookie 在 maxAge 秒后失效。此时cookie保存在硬盘中 如果为负数,该 cookie 为临时 cookie ,关闭浏览器即失效。此时cookie保存在内存中 如果为 0,表示删除该 cookie 。默认为 -1。 |
expires | 过期时间,在设置的某个时间点后该 cookie 就会失效。 |
httpOnly | 如果给某个 cookie 设置了 httpOnly 属性,则无法通过 JS 脚本 读取到该 cookie 的信息,但还是能通过 Application 中手动修改 cookie,所以只是在一定程度上可以防止 XSS 攻击,不是绝对的安全 |
secure | 设置cookie仅在使用安全协议时传输。当 secure 值为 true 时,cookie 在 HTTP 中是无效,在 HTTPS 中才会被携带传输。使用 HTTPS 安全协议,可以保护 Cookie 在浏览器和 Web 服务器间的传输过程中不被窃取和篡改。 引出HTTP和HTTPS的区别 |
samesite | 问属性可以提这个点,可以引出XSS攻击和CSRF攻击 |
sameparty | 讲samesite可以提到这个,关于跨域携带cookie |
cookie的sameSite属性
以前是不认来源,只看目的。
比如:通过响应头在浏览器中设置了一个cookie
set-cookie: id=nian; domain=.a.com;
现在有三个请求:
1.网页www.a.com/index.html
的前端页面,去请求接口www.b.com/api
2.网页www.b.com/index.html
的前端页面,去请求接口www.a.com/api
√携带
3.网页www.a.com/index.html
的前端页面,去请求接口www.a.com/api
√携带
有什么作用
SameSite 属性的作用是限制第三方cookie的携带,对cookie的取用是既看来源,又看目的,从而可以阻止跨站请求伪造攻击(CSRF)
samesite属性值
属性值 | 描述 |
---|---|
strict | 浏览器将只发送相同站点请求的 Cookie,避免CSFR攻击 |
Lax(默认) | 从第三方站点的链接打开和从第三方站点提交 Get 方式的表单这两种方式都会携带 Cookie |
None | 不做限制,之前的不认来源,只看目的。 |
像a链接这种,Lax情况没有受到影响,依旧会带上三方cookie,这样可以保证从百度搜索中打开淘宝,是有登录状态的。
cookie如何跨域
以前通过设置Access-Control-Allow-Origin:具体来源
、Access-Control-Allow-Credentials:true
、xhr属性withCredentials:true
就可以跨域携带。但是这样可能会被CSRF攻击,所以浏览器新增sameSite
来限制第三方cookie。
sameSite
必须满足的条件
- 网站开启 https 并将 Cookie 的 Secure 属性设置为 true
- SameSite 属性设置为 None
- Access-Control-Allow-Origin 设置为具体的 origin,而不是 *
- Access-Control-Allow-Credentials 设置为 true
ajax 请求需要设置 xhr 的属性 withCredentials 为 true,服务器需要设置响应头部 Access-Control-Allow-Credentials: true
设置为none之后不能避免CSRF攻击
跨域的笔记:https://blog.csdn.net/qq_41370833/article/details/124698995
sameParty 首选
sameParty可以把跨站的站点合起来,设置cookie在这个集合内部不会被当作第三方cookie对待。
必须满足的条件
- SameSite 属性设置为不能为strict
- 网站开启 https 并将 Cookie 的 Secure 属性设置为 true
- 包含sameParty属性
案例
首先需要定义First-Party集合:在.taobao.com、.tmall.com和.alimama.com三个站的服务器下都加一个配置文件,放在/.well-know/目录下,命名为first-party-set。
其中一个是“组长”,暂定为.taobao.com,在它的的服务器下写入
// /.well-know/first-party-set
{
"owner":".taobao.com",
"members": [".tmall.com", ".alimama.com"]
}
在其他组员的服务器下写入
// /.well-know/first-party-set
{
"owner": ".taobao.com",
}
在发cookie时,需要注明same-party
属性
Set-Cookie: id=nian; SameParty; Secure; SameSite=Lax; domain=.taobao.com
作者:前端私教年年
链接:https://juejin.cn/post/7087206796351242248
来源:稀土掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
三者的区别
区别 | cookie | localStorage | sessionStorage |
---|---|---|---|
生命周期 | 可设置失效时间,没有设置的话,默认是关闭浏览器后失效 | 除非被手动清除,否则永久保存 | 仅在当前网页会话有效,关闭页面或浏览器后就会被清除 |
存放数据大小 | 不超过4kb | 5MB左右 | 5MB左右 |
使用范围 | 同域名下都会共享,(子域可以) 当前域下的js脚本不能访问其他域下的 cookie 因为同源策略 引出同源策略和跨域 | 相同浏览器的同源窗口都会共享 | 通过跳转的同源页面可以共享sessionStorage,同一个页面的不同窗口不可以共享 |
http请求 | 会自动把当前域名下所有未过期的Cookie一同发送给服务器 | 仅在浏览器中保存,不参与和服务器的通信 | 仅在浏览器中保存,不参与和服务器的通信 |
应用场景 | 本职工作并非本地存储,而是维持状态 | 本地存储工作 | 本地存储工作 |
两个同源页面之间怎么传参
html里localStorage用于本地键值对存储,可以在html里面通过监听storage
事件,监听到localStorage的变化,来完成页面之间的数据传输。
//A
function test() {
localStorage.setItem("a", '666')
}
//B
window.addEventListener('storage',(e) => {
if(e.key === 'a'){
let value = e.newValue;
}
})
localstorage的定时删除 --重写localstorage方法
localStorage.setItem('test',1234567);
let test = localStorage.getItem('test');
console.log(typeof test, test); //输入是number类型,输出是string类型
//删除
localStorage.removeItem('test')
1.什么场景需要删除localstorage里的数据
比如存储的数据太多了,定期清理。
比如七天免登录,token过期之后,也可以把对应的localstorage清除
2.怎么设置 localstorage 过期时间 自动删除它?
- 存入数据时,顺带传入过去时间;
- 获取数据时,判断当前是否过期,过期返回 undefined; 否则正常返回数据。
//age表示过多久失效
Storage.prototype.setStorageWithAge = (key,value,age) =>{
if(isNaN(age) || age<1) throw new Error("age must be a number");
const obj = {
data: value, //存储值
time: Date.now(), //存值时间戳
maxAge: age, //过期时间
};
localStorage.setItem(key, JSON.stringify(obj));
};
}
Storage.prototype.getStorageWithAge = key => {
const { data, time, maxAge } = JSON.parse(localStorage.getItem(key));
if (time + maxAge < Date.now()) {//说明已经过期了
localStorage.removeItem(key);
return undefined;
}
return data;
};
localStorage 和 sessionStorage 都继承自 Storage 对象, 所以我们可以扩展Storage原型方法。
token
面试题
- token认证流程
- token前端是存在哪里的
- 项目中为啥会使用token
- token和cookie的区别
- token session cookie区别
- token的存储为什么要用localStorage
token是什么
token是服务端生成的一串包含了用户信息等数据的一串字符串
- token 完全由应用管理,可以在多个服务间共享
- Token 可以避免 CSRF 攻击 , Cookie存在CSRF攻击的问题
token的认证过程
cookie和token的区别,为什么选cookie/token
cookie | token |
---|---|
浏览器的一种存储方式,默认不可以跨域。服务端发送到浏览器的cookie,浏览器会进行存储,请求时会自动携带一起发送到服务器 | token:服务器端生成的包含了用户信息等数据的一串字符串,发送请求时需要手动携带 |
cookie存储的体积不能超过4kb,无法跨域,移动端支持不好 | 存储面积更大, 支持移动端设备, 完全由应用管理,可以在多个服务间共享。 |
token存储在本地的哪里?Refresh Token
如何防止token泄露?
类似数字签名机制,利用时间戳和token加密算法 = token签名
比如JWT规范
- Header(头部) 翻译出来是一个 JSON 对象,描述 JWT 的元数据,比如签名使用的算法,令牌的类型
- Payload(有效荷载) 是用户信息经过加密之后生成的字符串,翻译出来是存放需要传递的JSON格式的数据。
- Signature(签名) 是这个token的签名,通常情况下是将前面的header和payload加上一个你自己定义的私钥字符串一起加密生成的字符串。
在本地的存储
- 存储在cookie中:会自动发送,cookie不可以跨域,需要服务器配合。移动端支持不友好。
- 可以设置
httpOnly
来防止被JavaScript读取,预防xss攻击。可以设置secure
,来保证token只在HTTPS下传输。设置sameParty来屏蔽不允许的第三方cookie,预防CSRF攻击
- 可以设置
- 存储在localStorage中,每次请求的时候放在HTTP请求头的Authorization字段里
- 存在的问题:同域会共享localStorage,容易受到xss攻击
- 优点是:存储空间大,可以防御CSRF攻击
token主动刷新
如果token过期,主动刷新token,利用与token相关联的refresh token,refresh token作用是获取新的token,过期时间比token的时间长。
将token过期的处理放在响应拦截器中,当返回的响应码为401时,说明token过期了,需要利用refresh token重新获取新的token。重新获取token之后,重发请求。
- 新token请求成功
- 更新本地token
- 再发一次请求A
- 新token请求失败
- 清空vuex中的token
- 携带请求地址,跳转到登陆页
Refresh Token 及过期时间是存储在服务器的数据库中,只有在申请新的 Token 时才会验证
身份认证 session机制和JWT机制
面试题
- JWT的原理是什么?session认证的原理是什么?区别是什么?
- 为什么不用cookie存储token,localStorage存储的信息能窃取到吗(可以)?
- token一旦被颁发很难被撤销,如果我想让一个用户失去登录状态应该怎么做
- 保存登录状态怎么做的?如果遇到登录成功之后,token失效怎么处理?
- JWT的组成部分
session方案 cookie+session
- 浏览器登录之后,服务器验证通过后,创建一个session对象,存放用户的相关信息,比如用户角色、过期时间等等。服务器向用户返回一个 session_id,写入用户的 Cookie。
- 浏览器自动把cookie存储在当前域名下,客户端再次发送请求时,通过请求头自动把当前域名下所有可用的Cookie发送给服务器
- 服务器根据sessionId 从session中查找对应的用户信息,进行验证响应
如果在 Session 有效期间用户一直在操作,这时候 expires 时间就应该刷新。频繁更新 session 会影响性能,可以在 session 快过期的时候再更新过期时间。
常用场景
session失效的问题
比如 A 服务器存储了 Session,当做了负载均衡后,假如一段时间内 A 的访问量激增,会转发到 B 进行访问,但是 B 服务器并没有存储 A 的 Session,会导致 Session 的失效。
解决方法:可以将session集中存储
单设备登录
假设只允许一个帐号在一个端下登录,如果换了一个端,需要把之前登录的端踢下线(默认情况下,同一个帐号可以在不同的端下同时登录的)。
这时候可以借助一个服务保存用户唯一标识和 sessionId 值的对应关系,如果同一个用户,但 sessionId 不一样,则不允许登录或者把之前的踢下线(删除旧 session )。
JWT方案
JSON Web Token(简称 JWT)是目前最流行的跨域认证解决方案。
- 浏览器登录后,服务器验证通过后,利用密钥(服务器端存储)经过加密后生成Token字符串(Token中包含了用户信息),将生成的Token字符串返回给客户端
- 客户端通过代码将Token存储到本地
- 客户端再次发送请求时,通过请求头的Authorization字段(手动设置),将Token发送给服务器
//Bearer 开头
Authorization:Bearer <token>
//request请求拦截器拦截器中
config.headers['Authorization'] = 'Bearer ' + getToken()
- 服务器通过还原Token字符串来认证用户信息
token和JWT
token是需要存储在服务器端的,JWT不用存储到数据库中
-
Token:服务端验证客户端发送过来的 Token 时,还需要查询数据库获取用户信息,然后验证 Token 是否有效。
-
JWT: 将 Token 和 Payload 加密后存储于客户端,服务端只需要使用密钥解密进行校验(校验也是 JWT 自己实现的)即可,不需要查询或者减少查询数据库,因为 JWT 自包含了用户信息和加密的数据。
如何选择JWT方案和session方案
session
- 将 session 存储在服务器里面,当用户同时在线量比较多时,这些 session 会占据较多的内存,需要在服务端定期的去清理过期的 session
- 当网站采用集群部署的时候,会遇到多台 web 服务器之间如何做 session 共享的问题。
- session基于cookie,会存在cookie跨域问题
- 移动端对 cookie 的支持不是很好,而 session 需要基于 cookie 实现,所以移动端常用的是 token
JWT
- 由于服务器不需要存储 Session 状态,因此使用过程中无法废弃某个 Token 或者更改 Token 的权限,JWT 无法实时刷新。
如何提前失效JWT? 维护黑名单,存储到数据库中 - 因为 JWT 并不依赖 Cookie 的,所以你可以使用任何域名提供你的 API 服务而不需要担心跨域资源共享问题(CORS)
选择jwt
- 同时在线人数很多,减轻服务器维护 Session 的开销
- 存储在前端无状态,集群情况下使用 JWT 逻辑更简单
- 网页端与移动端共用 API 的情况
最后
以上就是悲凉板栗为你收集整理的浏览器本地缓存 localstorage/sessionstorage/cookie - 身份认证 cookie/session/token浏览器本地缓存 localstorage/sessionstorage/cookie的全部内容,希望文章能够帮你解决浏览器本地缓存 localstorage/sessionstorage/cookie - 身份认证 cookie/session/token浏览器本地缓存 localstorage/sessionstorage/cookie所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复