浏览器本地缓存 localstorage/sessionstorage/cookie - 身份认证 cookie/session/token

浏览器本地缓存 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的特点

  1. cookie是不可跨域的,每个cookie都会绑定单一的域名,无法在别的域名下获取使用
  2. cookie 是服务器发送到用户浏览器并保存在本地不超过4K的数据,当用户端发起请求时,会自动把当前域名下所有未过期的Cookie一同发送给服务器

会限制第三方cookie的携带。
什么是第三方cookie
第三方cookie指非同站(顶级域名+二级域名同),比如ai.taobao.comwww.taobao.com是同站的,domain一列中显示和当前域名不同站的就是三方cookie。
在这里插入图片描述
1.可以忽略协议和端口共享
http:// www.baidu.com:8080https:// www.baidu.com:9090是可以共享cookie
2.顶级域名+二级域名相同可以共享
https:// running.aaa.com.cnhttps:// slave.aaa.com.cn是可以共享cookie

cookie的主要属性

属性说明
domain默认是当前域名,请求哪些域名才会被携带
maxAgecookie 失效的时间,单位秒。
如果为正数,则该 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:truexhr属性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
来源:稀土掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

三者的区别

区别cookielocalStoragesessionStorage
生命周期可设置失效时间,没有设置的话,默认是关闭浏览器后失效除非被手动清除,否则永久保存仅在当前网页会话有效,关闭页面或浏览器后就会被清除
存放数据大小不超过4kb5MB左右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

cookietoken
浏览器的一种存储方式,默认不可以跨域。服务端发送到浏览器的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

在这里插入图片描述

  1. 浏览器登录之后,服务器验证通过后,创建一个session对象,存放用户的相关信息,比如用户角色、过期时间等等。服务器向用户返回一个 session_id,写入用户的 Cookie。
  2. 浏览器自动把cookie存储在当前域名下,客户端再次发送请求时,通过请求头自动把当前域名下所有可用的Cookie发送给服务器
  3. 服务器根据sessionId 从session中查找对应的用户信息,进行验证响应

如果在 Session 有效期间用户一直在操作,这时候 expires 时间就应该刷新。频繁更新 session 会影响性能,可以在 session 快过期的时候再更新过期时间。

常用场景

session失效的问题
比如 A 服务器存储了 Session,当做了负载均衡后,假如一段时间内 A 的访问量激增,会转发到 B 进行访问,但是 B 服务器并没有存储 A 的 Session,会导致 Session 的失效。

解决方法:可以将session集中存储

单设备登录
假设只允许一个帐号在一个端下登录,如果换了一个端,需要把之前登录的端踢下线(默认情况下,同一个帐号可以在不同的端下同时登录的)。
这时候可以借助一个服务保存用户唯一标识和 sessionId 值的对应关系,如果同一个用户,但 sessionId 不一样,则不允许登录或者把之前的踢下线(删除旧 session )。

JWT方案

JSON Web Token(简称 JWT)是目前最流行的跨域认证解决方案。

在这里插入图片描述
在这里插入图片描述

  1. 浏览器登录后,服务器验证通过后,利用密钥(服务器端存储)经过加密后生成Token字符串(Token中包含了用户信息),将生成的Token字符串返回给客户端
  2. 客户端通过代码将Token存储到本地
  3. 客户端再次发送请求时,通过请求头的Authorization字段(手动设置),将Token发送给服务器
//Bearer 开头
Authorization:Bearer <token>
//request请求拦截器拦截器中
config.headers['Authorization'] = 'Bearer ' + getToken() 
  1. 服务器通过还原Token字符串来认证用户信息
token和JWT

token是需要存储在服务器端的,JWT不用存储到数据库中

  • Token:服务端验证客户端发送过来的 Token 时,还需要查询数据库获取用户信息,然后验证 Token 是否有效。

  • JWT: 将 Token 和 Payload 加密后存储于客户端,服务端只需要使用密钥解密进行校验(校验也是 JWT 自己实现的)即可,不需要查询或者减少查询数据库,因为 JWT 自包含了用户信息和加密的数据。

如何选择JWT方案和session方案

session

  1. 将 session 存储在服务器里面,当用户同时在线量比较多时,这些 session 会占据较多的内存,需要在服务端定期的去清理过期的 session
  2. 当网站采用集群部署的时候,会遇到多台 web 服务器之间如何做 session 共享的问题。
  3. session基于cookie,会存在cookie跨域问题
  4. 移动端对 cookie 的支持不是很好,而 session 需要基于 cookie 实现,所以移动端常用的是 token

JWT

  1. 由于服务器不需要存储 Session 状态,因此使用过程中无法废弃某个 Token 或者更改 Token 的权限,JWT 无法实时刷新。
    如何提前失效JWT? 维护黑名单,存储到数据库中
  2. 因为 JWT 并不依赖 Cookie 的,所以你可以使用任何域名提供你的 API 服务而不需要担心跨域资源共享问题(CORS)

选择jwt

  • 同时在线人数很多,减轻服务器维护 Session 的开销
  • 存储在前端无状态,集群情况下使用 JWT 逻辑更简单
  • 网页端与移动端共用 API 的情况
  • 3
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值