了解 Web:HTTP Cookie 🍪

2025-06-07

了解 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 ...
在那里你会看到以下内容:

cookies-应用程序.png

绿色下划线的是选项。名称不言自明。其余的是我们需要理解的。

  • 领域

每个 cookie 都有一个所属的域模式,并且只能由该特定的域模式访问。

cookie-1如果添加了名为 的 Cookie .motherfuckingwebsite.com(注意.),那么motherfuckingwebsite.com的任何子域名cookie-1都可以访问它。例如:可以被 域名及其子域名访问,例如等等。cookie-1motherfuckingwebsite.comwww.motherfuckingwebsite.comwww2.motherfuckingwebsite.com

cookie-2如果为子域名添加了名为的 Cookie xyz.motherfuckingwebsite.com,则该 Cookie 只能由其子域名和其自身访问。例如:cookie-2可由子域名xyz.motherfuckingwebsite.com及其子域名访问abc.xyz.motherfuckingwebsite.com,依此类推。

您可以在RFC2109上阅读更多内容

  • 小路

假设你想让某个 Cookie 可以被特定路径访问,那么可以使用此选项。稍后我会解释。

  • 到期/最大年龄

正如我在文章开头提到的,“Cookie 是临时数据”,也就是说,它们具有有效期,超过有效期就会过期。有效期是如何确定的呢?由 Web 服务/网站决定。每当网站/Web 服务创建 Cookie 时,都会提到其有效期。

HttpOnlySecureSameSite将在安全部分解释。

好了!闲话少叙。我们来做些饼干,加热一下你的烤箱(浏览器)吧。

👨‍💻 客户之道

首先,我们将讨论如何使用 JS 从客户端(即从浏览器)创建 cookie,这非常简单。

document.cookie

如何使用 JS 查看现有的 Cookie?只需document.cookie在控制台中使用,您将看到以下内容:

cookies-console.png

请注意,每个 cookie 都以分号 ( ;) 分隔。

  • 创建简单的cookie
document.cookie="itsME=1"
Enter fullscreen mode Exit fullscreen mode

注意:以上代码不会覆盖 Cookie,它只会创建一个新的 Cookie。

cookie-bake.png

您可以看到它motherfuckingwebsite.com现在根据我们上面讨论的属性为域定义,www.motherfuckingwebsite.com应该无法访问 cookie itsME

cookie-子域名.png

我们没有看到我们创建的 cookie,因此我们验证了属性。

  • 设置cookie路径

把Path选项添加到我们的 Cookie 中怎么样?开始吧……

document.cookie="itsMe=7; path=/test";
Enter fullscreen mode Exit fullscreen mode

上述代码只会设置 cookie,motherfuckingwebsite.com/test并且只能通过该 cookie 访问。以下是示例。

document.cookie="itsME=7; path=/test";
Enter fullscreen mode Exit fullscreen mode

cookie 路径.png

图 1:我们正在访问 cookie,motherfuckingwebsite.com但没有这样的 cookie。

图 2:我们正在访问 cookiemotherfuckingwebsite.com/test并且我们可以看到它。

  • 设置 Cookie 有效期

让我们创建一个带有有效期的 Cookie。现在我们可以通过两种方式来实现。

  1. 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()}`; 
Enter fullscreen mode Exit fullscreen mode
  1. Max-age:以时间(以为单位)作为值。
//86400 i.e 24 hours in seconds
document.cookie=`itsME3=3;max-age=86400`; 
Enter fullscreen mode Exit fullscreen mode

上面我们创建了两个 Cookie,有效期均为 24 小时,自创建之日起生效。您可以在这里比较我们目前设置的所有三个 Cookie。

cookie 过期时间.png

注意!在Expires/Max-age部分,你可以看到ItsME2cookieItsME3中包含日期和时间,但ItsME实际显示的是session。这是因为,如果你没有设置 cookie 的过期时间,浏览器会将其视为会话 cookie,并在你关闭浏览器后立即过期。来吧,试试看。

💡 前往didthanoskill.me,在 URL 栏中查找 Cookie。你会看到有 1 个 Cookiedocument.cookie正在使用中。但在浏览器控制台中查看时,返回了一个空字符串,这很奇怪。在开发者工具的“应用程序”选项卡中,你也看不到任何 Cookie。知道为什么会这样吗?提示:查看源代码,如果仍然不明白,请在开发者工具中运行调试器来了解原因。

🖥️ 服务器方式

我们了解了客户端创建 Cookie 的方式。现在我们将从服务器端创建 Cookie,我将使用NodeJSExpress来实现。

基本上发生的情况是,当客户端向服务器发出请求时,服务器会以包含标头的响应进行响应,并且在该标头中,有一个选项告诉浏览器创建 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<");
})
Enter fullscreen mode Exit fullscreen mode

我们拥有它。

  • 设置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<");
});
Enter fullscreen mode Exit fullscreen mode

给出以下结果:

cookie-ss-路径.png

cookie-ss-path2.png

其他选项也是如此。

🔒 安全

安全是这里讨论的一个非常重要的话题。如前所述,社交媒体等服务会使用各种 Cookie 来保持您的登录状态。如果这些 Cookie 落入攻击者手中,他们就能轻松入侵您的帐户,并窃取您所知的一切。

当用户隐私成为关注点时,任何 Web 应用程序实现都应该在一定超时后使 cookie 数据无效,而不是依赖浏览器来执行此操作,这一点很重要。

如果您使用 cookie 来存储某些数据并随后将其呈现在 DOM 中(这是一种非常糟糕的做法),那么请确保保持有效的格式,它们应该使用内置的 encodeURIComponent 函数进行转义:

var cookie_name="mycookie";
var cookie_value="myvalue";
document.cookie = `${encodeURIComponent(cookie_name)}=${encodeURIComponent(cookie_value)}`;
Enter fullscreen mode Exit fullscreen mode

在客户端方式部分,我们轻松地使用 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<");
});
Enter fullscreen mode Exit fullscreen mode

您将在“应用程序”选项卡(开发者工具)中的“HttpOnly”下看到一个勾号 (✔️)。尝试使用 JS 访问它。

如果您的 Cookie 包含敏感内容,则可能需要通过HTTPS发送。为此,您必须包含安全选项,如下所示。

//client side
document.cookie = "ItsMeSecure=6; secure";
Enter fullscreen mode Exit fullscreen mode
//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<");
});
Enter fullscreen mode Exit fullscreen mode

samesite SameSite 阻止浏览器发送跨站请求时附带的 cookie。可能的值为laxstrictnone

lax值将为所有同站点请求和顶级导航 GET 请求发送 cookie。这对于用户跟踪来说已经足够,但它可以防止许多CSRF攻击。这是现代浏览器中的默认值。

严格值将阻止浏览器在所有跨站点浏览环境中将 cookie 发送到目标站点,即使在遵循常规链接时也是如此。

none明确表示不应用任何限制。此 Cookie 将在所有请求中发送 - 包括跨站点请求和同站点请求。

所以请务必谨慎使用 Cookie 🦉。
如有任何问题或建议改进内容,欢迎随时提出。

🥳 现在是时候用一句话来总结这篇文章了

“机会不是凭空而来的,而是你创造的。”——克里斯·格罗瑟

文章来源:https://dev.to/souvikinator/know-the-web-http-cookie-131d
PREV
面向经验丰富的开发人员的 20 个高级 JavaScript 技巧
NEXT
在 VS Code 窗口中迷失了?