96 # クッキー

CookieとセッションとsessionStorageとlocalStorage

  • localStorage と sessionStorage はローカル ストレージ (リクエストの送信時には送信されません) であり、ドメインを越えることはできません。
  • localStorage はブラウザを閉じた後はクリアされないため、手動でクリアする必要があります。
  • sessionStorage はブラウザを閉じると破棄されます。
  • http はステートレスであり、Cookie を通じて状態を作成できます (ブラウザとサーバーの両方が Cookie を設定できます)。デフォルトでは、Cookie はリクエストが送信されるたびに送信されます。
  • Cookie は安全ではありません。データはクライアント側に保存されるため、改ざんされる可能性があります。機密情報は保存できません。
  • セッションは Cookie に基づいており、Cookie メカニズムを通じてサーバー側のストレージ スペースを作成します。
  • セッションは Cookie より安全です。サービスを再起動するたびに失われます。セッションを保存するには Redis を使用できます。

サーバー経由で Cookie を書き込む

  • ドメイン ドメイン名の設定。デフォルトは現在のドメイン名です。設定されている場合Domain=mozilla.org、Cookie はサブドメイン名にも含まれます (例developer.mozilla.org: )。
  • パス path (/ は任意のパスを表します) は、書き込み時の Cookie のパスを制限します。
  • exipres 絶対時間/最大経過時間相対時間
  • httpOnly クライアントが Cookie を操作できるかどうか

例:

const http = require("http");
const querystring = require("querystring");

const server = http.createServer(function (req, res) {
    
    
    // 通过服务端写入 cookie
    console.log(req.headers.cookie);
    if (req.url === "/read") {
    
    
        // 读取cookie
        res.end(JSON.stringify(querystring.parse(req.headers.cookie, "; ", "=")));
    } else if (req.url === "/write") {
    
    
        // 设置cookie
        res.setHeader("Set-Cookie", [
            `name=kaimo; domain=.kaimo.com; expires=${
      
      new Date(Date.now() + 10 * 1000).toGMTString()}`,
            "age=313; max-age=10; httpOnly"
        ]);
        res.end("write ok");
    } else {
    
    
        res.end("NOT FOUND");
    }
});

server.listen(3000);

console.log("Server running at http://127.0.0.1:3000/");

注:C:\Windows\System32\drivers\etc\hostsファイルを開いて、カスタムのローカル アクセス ドメイン名を追加できます。

127.0.0.1 a.kaimo.com
127.0.0.1 b.kaimo.com

http://a.kaimo.com:3000/write次に、それぞれ Cookie の書き込み、Cookie の読み取りにアクセスしhttp://a.kaimo.com:3000/readhttp://b.kaimo.com:3000/read

ここに画像の説明を挿入します

Cookie の読み取りと書き込みをカプセル化する

const http = require("http");
const querystring = require("querystring");

const server = http.createServer(function (req, res) {
    
    
    // 读取cookie
    req.getCookie = function (key) {
    
    
        let cookieObj = querystring.parse(req.headers.cookie, ";", "=");
        return cookieObj[key];
    };
    // 设置cookie
    let arr = [];
    res.setCookie = function (key, value, options = {
     
     }) {
    
    
        let opts = [];
        if (options.domain) {
    
    
            opts.push(`domain=${
      
      options.domain}`);
        }
        if (options.path) {
    
    
            opts.push(`domain=${
      
      options.path}`);
        }
        if (options.maxAge) {
    
    
            opts.push(`max-age=${
      
      options.maxAge}`);
        }
        if (options.httpOnly) {
    
    
            opts.push(`httpOnly`);
        }
        arr.push(`${
      
      key}=${
      
      value}; ${
      
      opts.join("; ")}`);
        res.setHeader("Set-Cookie", arr);
    };
    // 通过服务端写入 cookie
    console.log(req.headers.cookie);
    if (req.url === "/read") {
    
    
        res.end(req.getCookie("name") || "empty");
    } else if (req.url === "/write") {
    
    
        res.setCookie("name", "kaimo", {
    
    
            domain: ".kaimo.com",
            expires: `${
      
      new Date(Date.now() + 10 * 1000).toGMTString()}`
        });
        res.setCookie("age", "313", {
    
    
            maxAge: "10",
            httpOnly: true
        });
        res.end("write ok");
    } else {
    
    
        res.end("NOT FOUND");
    }
});

server.listen(3000);

console.log("Server running at http://127.0.0.1:3000/");

Cookieのセキュリティ問題

ブラウザにCookieを設定する際に署名を追加し、データの内容に基づいて独自の署名(MD5)を作成することができますが、この方法は偽造される可能性があります。

もう 1 つの方法は、sha256 ソルティング アルゴリズムを使用して、コンテンツと秘密キーに基づいて署名を計算することです (元に戻すことはできません)。同じ秘密キーを使用した署名の結果は同じです。

暗号学においては、パスワードの任意の固定位置に特定の文字列を挿入し、元のパスワードでハッシュした結果と一致しないようにすることを「ソルティング」と呼びます。

const http = require("http");
const querystring = require("querystring");
const crypto = require("crypto");

// 秘钥
const secret = "kaimo313";

// 为了编码能在网络中安全顺畅传输,这里可以直接把 / + = 三个符号置空
const sign = (value) =>
    crypto
        .createHmac("sha256", secret)
        .update(value)
        .digest("base64")
        .replace(/\/|\+|\=/g, "");

const server = http.createServer(function (req, res) {
    
    
    // 读取cookie
    req.getCookie = function (key, options) {
    
    
        let cookieObj = querystring.parse(req.headers.cookie, ";", "=");
        if (options.signed) {
    
    
            let [value, s] = (cookieObj[key] || "").split(".");
            let newSign = sign(value);
            if (newSign === s) {
    
    
                // 签名一致,说明这次的内容是没有被改过的
                return value;
            } else {
    
    
                // 签名被篡改了,不能使用
                return undefined;
            }
        }
        return cookieObj[key];
    };
    // 设置cookie
    let arr = [];
    res.setCookie = function (key, value, options = {
     
     }) {
    
    
        let opts = [];
        if (options.domain) {
    
    
            opts.push(`domain=${
      
      options.domain}`);
        }
        if (options.path) {
    
    
            opts.push(`domain=${
      
      options.path}`);
        }
        if (options.maxAge) {
    
    
            opts.push(`max-age=${
      
      options.maxAge}`);
        }
        if (options.httpOnly) {
    
    
            opts.push(`httpOnly`);
        }
        if (options.signed) {
    
    
            value = value + "." + sign(value);
        }
        arr.push(`${
      
      key}=${
      
      value}; ${
      
      opts.join("; ")}`);
        res.setHeader("Set-Cookie", arr);
    };
    // 通过服务端写入 cookie
    console.log(req.headers.cookie);
    if (req.url === "/read") {
    
    
        res.end(
            req.getCookie("name", {
    
    
                signed: true
            }) || "empty"
        );
    } else if (req.url === "/write") {
    
    
        res.setCookie("name", "kaimo", {
    
    
            domain: ".kaimo.com",
            expires: `${
      
      new Date(Date.now() + 10 * 1000).toGMTString()}`,
            signed: true // 加签名
        });
        res.setCookie("age", "313", {
    
    
            maxAge: "10",
            httpOnly: true
        });
        res.end("write ok");
    } else {
    
    
        res.end("NOT FOUND");
    }
});

server.listen(3000);

console.log("Server running at http://127.0.0.1:3000/");

ここに画像の説明を挿入します
Cookieの値を変更する

ここに画像の説明を挿入します

おすすめ

転載: blog.csdn.net/kaimo313/article/details/133351870