发布时间:2023-07-27 12:00
HTTP 是无状态的协议,每个请求都是完全独立的,服务端无法确认当前访问者的身份信息,无法分辨上一次的请求发送者和这一次的发送者是不是同一个人。所以服务器与浏览器为了进行会话跟踪(知道是谁在访问我),就必须主动的去维护一个状态,这个状态用于告知服务端前后两个请求是否来自同一浏览器。而这个状态需要通过 cookie 或者 session 去实现。
cookie的特点
cookie的主要属性
属性 | 说明 |
---|---|
domain | 指定 cookie 所属域名,默认是当前域名 |
maxAge | cookie 失效的时间,单位秒。 如果为正数,则该 cookie 在 maxAge 秒后失效。此时cookie保存在硬盘中 如果为负数,该 cookie 为临时 cookie ,关闭浏览器即失效。此时cookie保存在内存中 如果为 0,表示删除该 cookie 。默认为 -1。 |
expires | 过期时间,在设置的某个时间点后该 cookie 就会失效。 |
httpOnly | 如果给某个 cookie 设置了 httpOnly 属性,则无法通过 JS 脚本 读取到该 cookie 的信息,但还是能通过 Application 中手动修改 cookie,所以只是在一定程度上可以防止 XSS 攻击,不是绝对的安全 引出XSS攻击和CSRF |
secure | 设置cookie仅在使用安全协议时传输。当 secure 值为 true 时,cookie 在 HTTP 中是无效,在 HTTPS 中才会被携带传输。使用 HTTPS 安全协议,可以保护 Cookie 在浏览器和 Web 服务器间的传输过程中不被窃取和篡改。 引出HTTP和HTTPS的区别 |
samesite | 问属性可以提这个点,可以引出XSS攻击和CSRF攻击 |
sameparty | 讲samesite可以提到这个,关于跨域携带cookie |
原生js操作cookie
/*
"A=1;B=2;..."
*/
function getCookie(name){
let strcookie = document.cookie;//获取cookie字符串
//设置document document.cookie = '.....'
let arrcookie = strcookie.split(";");//分割
//遍历匹配
for ( let i = 0; i < arrcookie.length; i++) {
let arr = arrcookie[i].split("=");
if (arr[0] == name){
return decodeURIComponent(arr[1]);//返回转义之后的结果
}
}
return "";
}
1.浏览器首次向服务器发起请求。
2.服务器响应时,会发送 Set-Cookie 响应头;浏览器会把这个头写入 Cookie。
3.在 Cookie 到期前,浏览器访问该域下的所有请求,都会带上这个 Cookie。
新版本的谷歌浏览器默认屏蔽第三方的cookie
有什么作用
SameSite 属性可以让 Cookie 在跨站请求时不会被发送,从而可以阻止跨站请求伪造攻击(CSRF)
samesite属性值
属性值 | 描述 |
---|---|
strict | 浏览器将只发送相同站点请求的 Cookie |
Lax(默认) | 从第三方站点的链接打开和从第三方站点提交 Get 方式的表单这两种方式都会携带 Cookie |
None | 无论是否跨站都会发送 Cookie |
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
必须满足的条件
samesite=none
前提是secure属性为true,也就是必须使用https协议。
后续可能不可以设置成none了
跨域的笔记:https://blog.csdn.net/qq_41370833/article/details/124698995
sameParty可以把跨站的站点合起来,设置cookie在这个集合内部不会被当作第三方cookie对待。
必须满足的条件
案例
首先需要定义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行为都是在网关层进行处理的,基本不会出现带给第三方的情况。
区别 | cookie | localStorage | sessionStorage |
---|---|---|---|
生命周期 | 可设置失效时间,没有设置的话,默认是关闭浏览器后失效 | 除非被手动清除,否则永久保存 | 仅在当前网页会话有效,关闭页面或浏览器后就会被清除 |
存放数据大小 | 不超过4kb | 5MB左右 | 5MB左右 |
使用范围 | 同域名下都会共享,(子域可以) 当前域下的js脚本不能访问其他域下的 cookie 因为同源策略 引出同源策略和跨域 |
相同浏览器的同源窗口都会共享 | 通过跳转的同源页面可以共享sessionStorage,同一个页面的不同窗口不可以共享 |
http请求 | 会自动把当前域名下所有未过期的Cookie一同发送给服务器 | 仅在浏览器中保存,不参与和服务器的通信 | 仅在浏览器中保存,不参与和服务器的通信 |
应用场景 | 本职工作并非本地存储,而是维持状态 | 本地存储工作 | 本地存储工作 |
同源政策主要限制了三个方面
当前域下的 js 脚本不能访问其他域下的 cookie、localStorage
当前域下的 js 脚本不能操作访问操作其他域下的 DOM。
当前域下 ajax 无法发送跨域请求。
两个同源页面之间怎么传参
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.setItem('test',1234567);
let test = localStorage.getItem('test');
console.log(typeof test, test); //输入是number类型,输出是string类型
//删除
localStorage.removeItem('test')
1.什么场景需要删除localstorage里的数据
比如存储的数据太多了,定期清理。
比如七天免登录,token过期之后,也可以把对应的localstorage清除
2.怎么设置 localstorage 过期时间 自动删除它?
//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原型方法。
客户端第一次发送登录请求时,服务器通过响应头的形式向客户端发送身份认证的Cookie,客户端会自动将Cookie保存在浏览器中
当客户端每次请求服务器时,浏览器会自动将身份认证相关的Cookie,通过请求头的Cookie字段发送给服务器,用于服务器验证客户端的身份。
缺点
Session 机制有个缺点,比如 A 服务器存储了 Session,就是做了负载均衡后,假如一段时间内 A 的访问量激增,会转发到 B 进行访问,但是 B 服务器并没有存储 A 的 Session,会导致 Session 的失效。
JWT(JSON Web Token)是目前最流行的跨域认证解决方案
//Bearer 开头
Authorization:Bearer <token>
//request拦截器中
config.headers['Authorization'] = 'Bearer ' + getToken()
为什么不用cookie存储token?
cookie不允许跨域携带
登录之后将Token存储在本地LocalStorage+Vuex,每次发送请求都在请求头中携带Token。
如果token过期,主动刷新token,利用与token相关联的refresh token,refresh token作用是获取新的token,过期时间比token的时间长。
将token过期的处理放在响应拦截器中,当返回的响应码为401时,说明token过期了,需要利用refresh token重新获取新的token。重新获取token之后,重发请求。