了解 Web:HTTP Cookie 🍪
这篇文章,我们将学习 Cookie,当然不是那种可以吃的 Cookie。我们将讨论Cookie 的属性以及与 HTTP Cookie 相关的安全问题,还会学习如何创建 Cookie,所以请务必准备好牛奶和 Cookie,耐心阅读。
饼干时间!
在使用 Facebook、Instagram 或其他在线服务时,您是否注意到,一旦登录这些服务,再次访问这些网站时无需登录?
您搜索了“鞋子”,下次访问任何网站时,都会看到与鞋子相关的广告。
是否存在读心术?

简单来说,Cookie 是浏览器中存储的小块临时数据(键值对),用于帮助各种 Web 服务(如上所述)实现各种功能。这些 Web 服务/网站会将 Cookie 放入您的浏览器中,用于管理您在其服务/网站上的会话、追踪您的行为等。Cookie 还可用于记住用户先前在表单字段中输入的信息,例如姓名、地址、密码(这不是个好主意😅)和支付卡号。
现在,这些网站/网络服务能够访问他们放置在您的浏览器中的 cookie,这清楚地表明“每次您向网站/网络服务发出请求时,cookie 都会随请求一起发送到服务器”。
🕵️♂️ 开启福尔摩斯模式!
我们随便找一个网站,看看他们的 Cookie。顺便解释一下这些属性。所以我先去motherfuckingwebsite.com。在开发者工具中,打开“应用程序”选项卡,然后访问cookie > https://mothe ...。
在那里你会看到以下内容:
带绿色下划线的是选项。名称和值不言自明。其余的是我们需要理解的。
- 领域
每个 cookie 都有一个所属的域模式,并且只能由该特定的域模式访问。
cookie-1
如果添加了名为 的 Cookie .motherfuckingwebsite.com
(注意.
),那么motherfuckingwebsite.com的任何子域名cookie-1
都可以访问它。例如:可以被 域名及其子域名访问,例如或等等。cookie-1
motherfuckingwebsite.com
www.motherfuckingwebsite.com
www2.motherfuckingwebsite.com
cookie-2
如果为子域名添加了名为的 Cookie xyz.motherfuckingwebsite.com
,则该 Cookie 只能由其子域名和其自身访问。例如:cookie-2
可由子域名xyz.motherfuckingwebsite.com
及其子域名访问abc.xyz.motherfuckingwebsite.com
,依此类推。
您可以在RFC2109上阅读更多内容
- 小路
假设你想让某个 Cookie 可以被特定路径访问,那么可以使用此选项。稍后我会解释。
- 到期/最大年龄
正如我在文章开头提到的,“Cookie 是临时数据”,也就是说,它们具有有效期,超过有效期就会过期。有效期是如何确定的呢?由 Web 服务/网站决定。每当网站/Web 服务创建 Cookie 时,都会提到其有效期。
HttpOnly、Secure和SameSite将在安全部分解释。
好了!闲话少叙。我们来做些饼干,加热一下你的烤箱(浏览器)吧。
👨💻 客户之道
首先,我们将讨论如何使用 JS 从客户端(即从浏览器)创建 cookie,这非常简单。
document.cookie
如何使用 JS 查看现有的 Cookie?只需document.cookie
在控制台中使用,您将看到以下内容:
请注意,每个 cookie 都以分号 ( ;
) 分隔。
- 创建简单的cookie
document.cookie="itsME=1"
注意:以上代码不会覆盖 Cookie,它只会创建一个新的 Cookie。
您可以看到它motherfuckingwebsite.com
现在根据我们上面讨论的属性为域定义,www.motherfuckingwebsite.com
应该无法访问 cookie itsME
。
我们没有看到我们创建的 cookie,因此我们验证了属性。
- 设置cookie路径
把Path选项添加到我们的 Cookie 中怎么样?开始吧……
document.cookie="itsMe=7; path=/test";
上述代码只会设置 cookie,motherfuckingwebsite.com/test
并且只能通过该 cookie 访问。以下是示例。
document.cookie="itsME=7; path=/test";
图 1:我们正在访问 cookie,motherfuckingwebsite.com
但没有这样的 cookie。
图 2:我们正在访问 cookiemotherfuckingwebsite.com/test
并且我们可以看到它。
- 设置 Cookie 有效期
让我们创建一个带有有效期的 Cookie。现在我们可以通过两种方式来实现。
- Expires:以日期作为值。
//86400e3 is same as 86400000 i.e 24 hours in milliseconds
var exp_date=new Date(Date.now()+86400e3);
//refer template literals in JS if not familiar with ${}
document.cookie=`itsME2=2;expires=${exp_date.toGMTString()}`;
- Max-age:以时间(以秒为单位)作为值。
//86400 i.e 24 hours in seconds
document.cookie=`itsME3=3;max-age=86400`;
上面我们创建了两个 Cookie,有效期均为 24 小时,自创建之日起生效。您可以在这里比较我们目前设置的所有三个 Cookie。
注意!在Expires/Max-age部分,你可以看到ItsME2
cookieItsME3
中包含日期和时间,但ItsME
实际显示的是session。这是因为,如果你没有设置 cookie 的过期时间,浏览器会将其视为会话 cookie,并在你关闭浏览器后立即过期。来吧,试试看。
💡 前往didthanoskill.me,在 URL 栏中查找 Cookie。你会看到有 1 个 Cookie
document.cookie
正在使用中。但在浏览器控制台中查看时,返回了一个空字符串,这很奇怪。在开发者工具的“应用程序”选项卡中,你也看不到任何 Cookie。知道为什么会这样吗?提示:查看源代码,如果仍然不明白,请在开发者工具中运行调试器来了解原因。
🖥️ 服务器方式
我们了解了客户端创建 Cookie 的方式。现在我们将从服务器端创建 Cookie,我将使用NodeJS和Express来实现。
基本上发生的情况是,当客户端向服务器发出请求时,服务器会以包含标头的响应进行响应,并且在该标头中,有一个选项告诉浏览器创建 cookie。set-cookie
- 创建一个简单的 cookie。
const app=require("express")();
app.get("/",(req,res)=>{
//setting response header
res.setHeader("set-cookie",["itsSERVER1=h1"]);
res.send("this is https://localhost:2000/");
});
app.listen(2000,()=>{
console.log(">2000<");
})
我们拥有它。
- 设置cookie路径
const app=require("express")();
app.get("/",(req,res)=>{
/*can also use res.setHeader() instead of
res.cookie()*/
res.cookie("itsSERVER1","h1");
//for path /hahahayes
res.cookie("itsSERVER2","yeet!",{path:"/hahahayes"});
res.send("this is https://localhost:2000/");
});
app.get("/hahahayes",(req,res)=>{
res.send("this is https://localhost:2000/hahahayes");
});
app.listen(2000,()=>{
console.log(">2000<");
});
给出以下结果:
其他选项也是如此。
🔒 安全
安全是这里讨论的一个非常重要的话题。如前所述,社交媒体等服务会使用各种 Cookie 来保持您的登录状态。如果这些 Cookie 落入攻击者手中,他们就能轻松入侵您的帐户,并窃取您所知的一切。
当用户隐私成为关注点时,任何 Web 应用程序实现都应该在一定超时后使 cookie 数据无效,而不是依赖浏览器来执行此操作,这一点很重要。
如果您使用 cookie 来存储某些数据并随后将其呈现在 DOM 中(这是一种非常糟糕的做法),那么请确保保持有效的格式,它们应该使用内置的 encodeURIComponent 函数进行转义:
var cookie_name="mycookie";
var cookie_value="myvalue";
document.cookie = `${encodeURIComponent(cookie_name)}=${encodeURIComponent(cookie_value)}`;
在客户端方式部分,我们轻松地使用 JavaScript 访问了网站的 Cookie,因此攻击者可能会发现类似XSS 的漏洞,该漏洞使他们能够在网站上执行恶意 JS 代码并绕过登录。从开发人员的角度来看,追踪 XSS 非常困难,尤其是在功能繁多的大型应用程序中。因此,Cookie 中内置了一些安全功能,即使攻击者能够执行某些代码,也可以阻止此类攻击。
您可以查看“Hack this site basic 10”,它演示了不小心使用 cookie 会导致什么后果。
HttpOnly是 Web 服务器设置 Cookie 时使用的选项。该选项禁止任何 JavaScript 访问 Cookie。这是一种预防措施,用于防范某些攻击。
//server side
const app=require("express")();
app.get("/",(req,res)=>{
/*can also use res.setHeader() instead of
res.cookie()*/
res.cookie("itsSERVERsecure","100",{httpOnly:true});
res.send("this is https://localhost:2000/");
});
app.listen(2000,()=>{
console.log(">2000<");
});
您将在“应用程序”选项卡(开发者工具)中的“HttpOnly”下看到一个勾号 (✔️)。尝试使用 JS 访问它。
如果您的 Cookie 包含敏感内容,则可能需要通过HTTPS发送。为此,您必须包含安全选项,如下所示。
//client side
document.cookie = "ItsMeSecure=6; secure";
//server side
const app=require("express")();
app.get("/",(req,res)=>{
/*can also use res.setHeader() instead of
res.cookie()*/
res.cookie("itsSERVERsecure","100",{secure:true});
res.send("this is https://localhost:2000/");
});
app.listen(2000,()=>{
console.log(">2000<");
});
samesite SameSite 阻止浏览器发送跨站请求时附带的 cookie。可能的值为lax、strict或none。
lax值将为所有同站点请求和顶级导航 GET 请求发送 cookie。这对于用户跟踪来说已经足够,但它可以防止许多CSRF攻击。这是现代浏览器中的默认值。
严格值将阻止浏览器在所有跨站点浏览环境中将 cookie 发送到目标站点,即使在遵循常规链接时也是如此。
none值明确表示不应用任何限制。此 Cookie 将在所有请求中发送 - 包括跨站点请求和同站点请求。
所以请务必谨慎使用 Cookie 🦉。
如有任何问题或建议改进内容,欢迎随时提出。
🥳 现在是时候用一句话来总结这篇文章了
文章来源:https://dev.to/souvikinator/know-the-web-http-cookie-131d“机会不是凭空而来的,而是你创造的。”——克里斯·格罗瑟