在这篇文章中我们将深入探讨前端cookie、session、token和jwt等web开发中常见的身份认证和状态管理技术,它们在用户身份验证、数据存储授权和安全性方面发挥着重要作用,接下来开始逐一解释它们的含义、作用和各自的优势及其使用。
初识cookie
cookie是什么:也叫web cookie或浏览器cookie,是服务器发送到用户浏览器并保存在本地的一小块数据,浏览器会存储cookie并在下次向同一服务器再发起请求时携带并发送到服务器上,通常它用于告知服务端两个请求是否来自同一浏览器—如保持用户的登录状态,cookie使基于无状态的http协议记录稳定的状态信息成为了可能。
cookie主要用于以下三个方面:
1)会话状态管理
如用户登录状态、购物车、游戏分数或其他需要记录的信息
2)个性化设置
如用户自定义设置、主题和其他设置
3)浏览器行为追踪
如跟踪分析用户的行为等
比如我们随便拿一个我们以往登录的网站,F12找到应用,然后打开Cookie可以看到如下信息:
以下是cookie中常用的属性解释:
1)name:第一个也就是cookie的名字
2)value:第二个也就是cookie的值
3)Domain:第三个也就是可以知道cookie站点的域名
4)Path:第四个也就是定义了web站点上可以访问该cookie的目录
5)Expires:第五个也就是表示cookie的过期时间,即有效值
6)Size:第六个表示cookie的大小
7)HttpOnly:一种安全性增强的措施,旨在防止客户端的js代码访问该cookie
8)secure:告诉浏览器当前cookie只能用https协议进行传输
9)samesite:用来控制浏览器如何在跨站请求中发送cookies,防止一些常见的安全问题如跨站请求伪造(CSRF)攻击
10)
当浏览器向服务器发送http请求时,服务器可以在响应中通过Set-Cookie头部设置一个或多个cookie,这些cookie会被存储在客户端浏览器中,通常包括以下几个基本信息:
1)名称:cookie的名字(例如 user_id)。
值:cookie的内容或数据(例如 123456)。
2)过期时间:cookie的有效期。可以通过 Expires 或 Max-Age 指定。如果没有设置过期时间,cookie默认会在浏览器会话结束时过期(即浏览器关闭时)。
3)路径:指定cookie适用的路径,只有该路径下的网页才能访问这个cookie。
4)域:指定cookie适用的域,通常是发送cookie的服务器域名。
5)安全标志:如果设置了secure,则cookie只能通过https协议传输。
6)HttpOnly 标志:如果设置了HttpOnly,该cookie只能通过http协议访问,js无法访问增加了防止 XSS 攻击的安全性。
cookie的作用:主要用于在浏览器与服务器之间维持会话状态,通常在用户登录后浏览器会存储cookie以标识用户的身份,每次用户访问网站时浏览器会自动将对应的cookie随http请求一起发送给服务器,服务器校验通过之后就会通过set-cookie的方式发送给浏览器,下次浏览器发起请求的时服务器通过校验cookie即可,如下图所示:
cookie的原理:通过在客户端(即浏览器)存储小型数据,从而实现服务器与客户端之间的状态保持和信息传递,如下图所示:
cookie的主要工作流程如下:
1)首次访问网站:浏览器向服务器发送请求服务器根据需要通过set-cookie响应头发送cookie
2)浏览器存储cookie:将其与网站的域名、路径等关联,保证cookie在后续请求中可用
3)后续请求:浏览器自动将与该网站域名匹配的cookie添加到请求的cookie头部,服务器读取cookie进行身份验证或数据维护
4)服务器响应:服务器可以通过设置新的cookie或更新现有的cookie来管理会话状态
5)cookie过期/删除:浏览器会根据cookie的过期时间或set-cookie的指示删除无效cookie
cookie的生成:cookie主要有以下两种方式生成:
1)服务端生成:在http responee header中set-cookie
2)客户端生成:通过document.cookie设置
cookie的误用:cookie的设计初衷是用于维持http状态的,不用于存储数据,原因如下:
1)大小限制:每个cookie项只能存储4k数据
2)性能浪费:cookie附带在http请求上,请求量过大,会导致每个http请求变得非常庞大
cookie使用
document操作:对于前端来讲我们可以通过document进行对cookie的操作,在浏览器的控制台当中输入document.cookie就可以获取当前网页的部分cookie信息,获取的字段可以用split函数将其拆分开来,如下所示:
它的序列化方式是:k1=v1; k2=v2; k3=v3 的方式,在浏览器中实际存储的不只当前网页cookie,浏览器当中设置的cookie也是使用的document.cookie,在浏览器当中设置cookie的方式如下,在浏览器的cookie存储当中可以看到我们设置的cookie已经成功被存储了,方式是会话存储:
如果想执行cookie的删除操作的话,可以借助max-age属性,其特点就是max-age=-1意味着直接删除cookie,max-age=60意味着60秒之后删除cookie,可以通过如下的命令执行:
然后我们可以通过js代码来设置一个自带有效期的cookie,cookie的expires属性来为其指定一个终止日期,expires属性应该是一个GMT格式的日期字符串,表示cookie的过期时间,当浏览器的时间达到这个过期时间时,cookie就会被自动删除,如下:
function setCookieWithExpiration(name, value, daysToExpire) {
var date = new Date();
date.setTime(date.getTime() + (daysToExpire * 24 * 60 * 60 * 1000)); // 设置过期时间为指定的天数之后
var expires = "; expires=" + date.toUTCString(); // 转换为GMT格式的字符串
document.cookie = name + "=" + (value || "") + expires + "; path=/"; // 设置cookie
}
// 使用示例
setCookieWithExpiration('myCookie', 'myValue', 7); // 名为myCookie的cookie,值为myValue,7天后过期
当然读取和删除的功能操作也是和上面一样的,借助document进行操作,代码如下:
// 读取cookie
function getCookie(name) {
const value = `; ${document.cookie}`;
const parts = value.split(`; ${name}=`);
if (parts.length === 2) return parts.pop().split(';').shift();
}
getCookie(username) // jack
getCookie(password) // 123
// 删除Cookie,直接把expires属性指定一个过去的时间,cookie就会被自动删除
// 删除单个
function deleteCookie(name) {
document.cookie = name + '=;expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;';
}
deleteCookie('password');
// 删除所有
function deleteAllCookies() {
var cookies = document.cookie.split(";");
for (var i = 0; i < cookies.length; i++) {
var cookie = cookies[i];
var eqPos = cookie.indexOf("=");
var name = eqPos > -1 ? cookie.substr(0, eqPos) : cookie;
document.cookie = name + "=;expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;";
}
}
// 使用示例
deleteAllCookies();
判断是否存在cookie也可以采用如下的方式进行:
function hasCookie(name) {
var nameEQ = name + "=";
var ca = document.cookie.split(';');
for(var i=0;i < ca.length;i++) {
var c = ca[i];
while (c.charAt(0)==' ') c = c.substring(1,c.length);
if (c.indexOf(nameEQ) == 0) return true;
}
return false;
}
hasCookie('password'); // 不存在返回false
hasCookie('username'); // 存在返回true
js-cookie操作:前端我们也可以借助第三方库进行操作cookie,终端执行如下命令进行安装:
npm install js-cookie
安装完成之后我们就可以在文件中进行使用了,如下所示:
import Cookies from "js-cookie";
// 写入cookie
Cookies.set('name', 'value')
// 读取
Cookies.get('name') // => 'value'
Cookies.get('nothing') // => undefined
// 读取所有可见的cookie
Cookies.get()
// 删除某项cookie值
Cookies.remove('name')
当然我们也可以通过该第三方库进行设置cookie及其过期时间以及删除功能:
//1、存cookie set方法支持的属性有 : expires->过期时间 path->设置为指定页面创建cookie domain-》设置对指定域名及指定域名的子域名可见 secure->值有false和true ,表示设置是否只支持https,默认是false
Cookies.set('key', 'value'); //创建简单的cookie
Cookies.set('key', 'value', { expires: 27 });//创建有效期为27天的cookie
Cookies.set('key', 'value', { expires: 17, path: '' }); //可以通过配置path,为当前页创建有效期7天的cookie
let seconds = 10;
let expires = new Date(new Date() * 1 + seconds * 1000);
Cookies.set('username', 'tanggaowei', { expires: expires }); // 10 秒后失效
//2、取cookie
Cookies.get('key'); // 获取指定key 对应的value
Cookies.get(); //获取所有value
Cookies.getJSON('name'); // 如果存的是对象如{ foo: 'bar' },可以使用该命令解析
Cookies.getJSON(); // => { name: { foo: 'bar' } }
//3、删除cookie
Cookies.remove('key');//删除普通的cookie
Cookies.remove('name', { path: '' }); // 删除存了指定页面path的cookie
发送cookie请求:在前端想要发送包含cookie的请求时,需要确保以下几个方面的配置和操作:
1)确保服务器设置了正确的 Set-Cookie 头部:首先服务器需要在响应中设置正确的Set-Cookie头部,并且根据需要配置SameSite、Secure、HttpOnly等属性。例如:
Set-Cookie: sessionId=abc123; SameSite=Lax; Secure; HttpOnly
SameSite:控制 cookie 在跨站请求中的行为,设置为 Strict、Lax 或 None。
Secure:表明该 cookie 只能通过 HTTPS 传输。
HttpOnly:表示该 cookie 只能由服务器读取,客户端 JavaScript 无法访问。
2)前端发送请求时要包括cookies:前端在发送请求时需要配置withCredentials,尤其是在发送跨域请求时,才能确保浏览器携带cookies,只有需要处理跨域请求时才需要设置withCredentials对于同源请求,浏览器默认会发送cookies:
axios.defaults.withCredentials = true; // 全局设置
// 或者在单个请求中设置
axios.get('https://api.example.com/data', {
withCredentials: true
})
.then(response => {
// 处理响应
})
.catch(error => {
// 处理错误
});
3)确保跨域时服务器允许携带cookies:当你发送跨域请求时,服务器需要设置Access-Control-Allow-Credentials头为 true,否则浏览器不会发送cookies,同时服务器需要允许特定的来源(Access-Control-Allow-Origin),但这个值不能设置为 *,而是要设置为实际允许的域名:
Access-Control-Allow-Credentials: true
Access-Control-Allow-Origin: https://yourfrontenddomain.com
axios.get('https://api.example.com/data', {
headers: {
Cookie: 'your=cookie; another=cookie' // 这里的值应该是你希望发送的Cookie字符串
}
})
.then(response => {
// 处理响应
})
.catch(error => {
// 处理错误
});
总之:cookie扮演着重要的角色用于在客户端存储和传递小型数据,常见于会话管理、用户认证以及个性化设置等场景,通过前端js操作cookie我们能够灵活地读取、创建、更新和删除 cookie,从而提升用户体验:
1)读取cookie:可以通过 document.cookie 获取所有的 cookie 数据,注意它以键值对的形式存在,且不支持直接读取单个 cookie,因此需要进行字符串解析。
2)设置cookie:通过 document.cookie 设置 Cookie 时,需要指定键值对、过期时间、路径、域名等属性。合理的配置 SameSite、Secure 和 HttpOnly 等属性能提高cookie的安全性。
3)删除cookie:通过设置 expires 为过去的时间,或使用 max-age 为负数,可以清除 Cookie 数据。
4)跨域与安全性:在跨域请求中,前端需要确保使用 credentials: 'include'(或在 XMLHttpRequest 中设置 withCredentials)来携带 cookies,服务器需要配置 Access-Control-Allow-Credentials 和 Access-Control-Allow-Origin 来支持跨域的 Cookie 传递。同时,设置 Secure 和 SameSite 可以防止 CSRF 攻击和其他安全漏洞。
通过深入理解cookie的存储和传递机制,我们能够确保前端应用的稳定性和安全性,同时提升用户体验,特别是在处理用户认证、会话管理等场景时,前端开发者应当时刻关注cookie的存取权限、过期机制以及跨域时的安全性设置,以应对日益复杂的 Web 环境和潜在的安全威胁。
版权归原作者 亦世凡华、 所有, 如有侵权,请联系我们删除。