cookie 是以 K-V 形式,存储在浏览器中一种数据。它可以在服务端设置,也可以在浏览器端用 js 代码设置。它拥有 maxAge、domain、path 等属性,借助这些属性,可以实现父子域名之间的数据传递。

虽然 cookie 是 K-V 形式存储的,但是在设置 cookie 的值的时候,是直接给定形如key1=value1; key2=value2的字符串。它在服务器/浏览器端均可以设置:

  • 浏览器端:通过 js 代码来设置,例如 document.cookie = "firstName=dongyuanxin; path=/
  • 服务器端:通过给 Http Response Headers 中的Set-Cookie字段赋值,来设置 cookie。客户端接收到Set-Cookie字段后,将其存储在浏览器中。

在服务端,以 koajs 为例,设置 key 为id,value 为xxoo521.com的 cookie。代码如下:

const Koa = require("koa");
const Router = require("koa-router");
const serve = require("koa-static");
const port = 3333;
const app = new Koa();
const router = new Router();
router.get("/api", async (ctx, next) => {
    const cookie = ctx.cookies.get("id");
    if (!cookie) {
        // 设置 id = xxoo521.com
        ctx.cookies.set("id", "xxoo521.com");
    }
    ctx.response.body = "原文地址:xxoo521.com";
});
app.use(serve("."))
    .use(router.routes())
    .listen(port, () => {
        console.log("listen port:", port);
    });
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

# 代码调试

在启动上面代码,并且请求/api接口后。在 Chrome Dev Tools 中,能看到服务器返回的 Headers

的信息,如下图:

按照协议,浏览器应该成功保存了 cookies 的值。此时,找到Application => Storage => Cookies => 当前域名,即可验证 cookie

是否设置成功,如下图:

# 整体流程

以用户购买商品为例,整体流程如下:

  • 监测到浏览器客户端没有标识用户的 cookie,跳转到登陆界面
  • 用户账号密码登陆,后端验证,成功后,在Set-cookie中设置标识用户的 cookie
  • 登陆成功,保存用户标识的 cookie
  • 购买商品,自动携带用户身份的 cookie,后端验证无误后,购买成功

# 总结

由此可见,单纯的使用 cookie,需要将用户的身份信息保存在客户端,并不安全。除此之外,cookie 还有大小限制,以及只能使用字符串类型作为 value 值。

来自: 身份认证-cookie机制 | 心谭博客
作者:心谭
Star仓库:github