Cookie-parser は、Cookie 解析を実装するために使用される Express のミドルウェアで、公式のスキャフォールディングに組み込まれているミドルウェアの 1 つです。使い方はとても簡単ですが、使用中に問題が発生する場合があります。これは通常、Express + cookie-parser の署名と検証メカニズムを理解していないことが原因で発生します。この記事では、Express cookie-parser ミドルウェアの実装例を中心に紹介します。編集者が非常に優れていると考えたので、参考として共有します。編集者をフォローして見てみましょう。皆さんのお役に立てれば幸いです。
最も単純な例から Cookie パーサーの使用法を見てみましょう。ここではデフォルトの設定が使用されています。
Cookie 設定: Express の組み込みメソッド res.cookie() を使用します。
Cookie 解析: Cookie パーサー ミドルウェアを使用します。
var express = require('express'); var cookieParser = require('cookie-parser'); var app = express(); app.use(cookieParser()); app.use(function (req, res, next) { console.log(req.cookies.nick); // 第二次访问,输出chyingp next(); }); app.use(function (req, res, next) { res.cookie('nick', 'chyingp'); res.end('ok'); }); app.listen(3000);
現在のシナリオでは、Cookie パーサー ミドルウェアは大まかに次のように実装されています:
app.use(function (req, res, next) { req.cookies = cookie.parse(req.headers.cookie); next(); });
セキュリティ上の理由から、通常は Cookie に署名する必要があります。
この例は、いくつかの注意点を加えて次のように書き直されます:
cookieParser が初期化されるとき、署名キーとしてシークレットで渡します。
Cookie を設定するときは、signed を true に設定して、これから設定される Cookie に署名します。
Cookieを取得する場合は、req.cookiesまたはreq.signedCookiesを通じて取得できます。
var express = require('express'); var cookieParser = require('cookie-parser'); var app = express(); // 初始化中间件,传入的第一个参数为singed secret app.use(cookieParser('secret')); app.use(function (req, res, next) { console.log(req.cookies.nick); // chyingp console.log(req.signedCookies.nick); // chyingp next(); }); app.use(function (req, res, next) { // 传入第三个参数 {signed: true},表示要对cookie进行摘要计算 res.cookie('nick', 'chyingp', {signed: true}); res.end('ok'); }); app.listen(3000);
署名前のCookie値は chyingp 、署名後のCookie値は s%3Achyingp.uVofnk6k%2B9mHQpdPlQeOfjM8B5oa6mppny9d%2BmG9rD0 、デコード後は s:chyingp.uVofnk6k+9mHQpdP lQeOfjM8B5oa 6mppny9d+mG9rD0。
Cookie の署名と解析がどのように実装されるかを分析してみましょう。
Express は Cookie 値の署名を完了し、Cookie パーサーは署名付き Cookie の解析を実装します。どちらも同じ秘密キーを共有します。
Cookie 署名
Express の Cookie 設定 (署名を含む) はすべて res.cookie() メソッドを通じて実装されます。
簡略化されたコードは次のとおりです:
res.cookie = function (name, value, options) { var secret = this.req.secret; var signed = opts.signed; // 如果 options.signed 为true,则对cookie进行签名 if (signed) { val = 's:' + sign(val, secret); } this.append('Set-Cookie', cookie.serialize(name, String(val), opts)); return this; };
sign は署名関数です。疑似コードは次のとおりで、実際には cookie の元の値と hmac の後の値を連結します。
黒板に重要な点をマークしておきます。署名された Cookie の値には元の値が含まれています。
function sign (val, secret) { return val + '.' + hmac(val, secret); }
この秘密はどこから来たのでしょうか?これは、cookie-parser が初期化されるときに渡されます。次の疑似コードに示すように:
var cookieParser = function (secret) { return function (req, res, next) { req.secret = secret; // ... next(); }; }; app.use(cookieParser('secret'));
署名付き Cookie の解析
Cookie 署名のメカニズムを理解すると、署名付き Cookie を「解析」する方法が明確になります。この段階で、ミドルウェアは主に 2 つのことを行います:
署名付き Cookie に対応する元の値を抽出します
署名付き Cookie が正当かどうかを検証します
実装コードは次のとおりです:
// str:签名后的cookie,比如 "s:chyingp.uVofnk6k+9mHQpdPlQeOfjM8B5oa6mppny9d+mG9rD0" // secret:秘钥,比如 "secret" function signedCookie(str, secret) { // 检查是否 s: 开头,确保只对签过名的cookie进行解析 if (str.substr(0, 2) !== 's:') { return str; } // 校验签名的值是否合法,如合法,返回true,否则,返回false var val = unsign(str.slice(2), secret); if (val !== false) { return val; } return false; }
Judge Cookie の元の値を抽出します。値は比較的単純です。 unsign メソッドの名前がわかりにくいだけです。
一般に、署名は法的に検証されるだけであり、いわゆる副署名はありません。
unsign メソッドのコードは次のとおりです。
まず、受信した Cookie 値から元の値 A1 と署名値 B1 を抽出します。
次に、同じ秘密鍵を使用して A1 に署名し、A2 を取得します。
最後に、A2とB1が等しいかどうかに基づいて、署名が正当であるかどうかを判断します。
exports.unsign = function(val, Secret){
var str = val.slice(0, val.lastIndexOf('.')) , mac = exports.sign(str, secret); return sha1(mac) == sha1(val) ? str : false; };
の役割は主にセキュリティ上の理由で、Cookieの改ざんを防ぎセキュリティを強化します。
Cookie 署名が改ざんをどのように防止できるかを簡単な例で見てみましょう。
前の例に基づいて展開します。 Web サイトがニック Cookie を使用して、現在ログインしているユーザーを区別すると仮定します。前の例では、ログイン ユーザーの Cookie で、対応するニックネームの値は次のとおりです: (デコード後)
s:chyingp.uVofnk6k+9mHQpdPlQeOfjM8B5oa6mppny9d+mG9rD0
このとき、誰かが変更しようとしました目的の偽の ID を達成するための Cookie の値。たとえば、これを xiaoming に変更します:
s:xiaoming.uVofnk6k+9mHQpdPlQeOfjM8B5oa6mppny9d+mG9rD0
Web サイトがリクエストを受信すると、署名 Cookie を解析し、署名の検証が失敗したことがわかります。このことからクッキーは偽造されたものであると判断できる。
hmac("xiaoming", "secret") !== "uVofnk6k+9mHQpdPlQeOfjM8B5oa6mppny9d+mG9rD0"
もちろんそうではありません。
前のセクションの例では、ニックネーム Cookie の値のみを使用して、どのユーザーがログインしているかを判断しています。これは非常に悪い設計です。ただし、秘密鍵が不明な場合、署名付き Cookie を偽造することは困難です。ただし、ユーザー名が同じ場合、署名も同じになります。この場合、実際には偽造するのは非常に簡単です。
また、オープンソースコンポーネントのアルゴリズムは公開されているため、秘密鍵の安全性が鍵となり、秘密鍵が漏洩しないようにする必要があります。
他にもたくさんありますが、ここでは説明しません。
この記事では主に、Express + cookie-parser の署名と解析メカニズムについて比較的詳しく紹介します。
多くの同様のまとめ記事では、Cookie 署名が暗号化であると説明されていますが、これはよくある間違いであり、読者は注意する必要があります。
署名部分の導入には、簡単なセキュリティの知識が含まれており、この分野に慣れていない学生でもメッセージを残してコミュニケーションを取ることができます。説明の便宜上、一部の段落や表現が厳密ではない場合があります。間違いや漏れがございましたら、ご指摘ください。
関連する推奨事項: Express を実装して独自のサーバー インスタンスを構築する
node Express.Router インスタンスを使用した Node.js の詳細な説明
Express フレームワークでセッションを使用してログイン認証を実装する
以上がExpress Cookie パーサー ミドルウェアの包括的な習得の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。