>  기사  >  웹 프론트엔드  >  Express에서 쿠키 파서 미들웨어를 사용하는 방법

Express에서 쿠키 파서 미들웨어를 사용하는 방법

亚连
亚连원래의
2018-06-08 14:54:281727검색

이 글은 주로 Express 쿠키 파서 미들웨어 구현 예제에 대한 심층 분석을 소개합니다. 이제 이를 여러분과 공유하고 참고하겠습니다.

기사 소개

cookie-parser는 Express의 미들웨어로 쿠키 구문 분석을 구현하는 데 사용되며 공식 스캐폴딩에 내장된 미들웨어 중 하나입니다.

사용 방법은 매우 간단하지만 사용 중에 가끔 문제가 발생할 수 있습니다. 이는 일반적으로 Express + 쿠키 파서의 서명 및 확인 메커니즘에 대한 이해 부족으로 인해 발생합니다.

이 글에서는 Express + 쿠키 파서의 서명 및 확인 구현 메커니즘과 쿠키 서명이 웹사이트 보안을 강화하는 방법에 대한 심층적인 설명을 제공합니다.

텍스트 동기화는 GitHub 테마 시리즈 "Nodejs 학습 노트"에 포함되어 있습니다.

시작하기 예: 쿠키 설정 및 구문 분석

cookie-parser의 사용을 살펴보기 위해 가장 간단한 예부터 시작하겠습니다. 여기에는 구성이 사용됩니다.

  1. 쿠키 설정: Express의 내장 메소드 res.cookie() 를 사용하세요.

  2. 쿠키 구문 분석: 쿠키 파서 미들웨어를 사용합니다.

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);

현재 시나리오에서 쿠키 파서 미들웨어는 대략 다음과 같이 구현됩니다.

app.use(function (req, res, next) {
 req.cookies = cookie.parse(req.headers.cookie);
 next();
});

고급 예: 쿠키 서명 및 구문 분석

보안상의 이유로 일반적으로 쿠키에 서명해야 합니다.

예제는 몇 가지 참고 사항과 함께 다음과 같이 다시 작성되었습니다.

  1. cookieParser가 초기화되면 서명 키로 비밀을 전달합니다.

  2. 쿠키를 설정할 때 signed를 true로 설정하여 설정하려는 쿠키에 서명하세요.

  3. 쿠키를 얻을 때 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);

서명 전 쿠키 값은 chyingp이고, 서명 후 쿠키 값은 s%3Achyingp.uVofnk6k%2B9mHQpdPlQeOfjM8B5oa6mppny9d%2BmG9rD0이며, 디코딩 후 쿠키 값은 다음과 같습니다. s :chyingp.uVofnk6k+9mHQpdPlQeOfjM8B5oa6mppny9d+mG9rD0. chyingp ,签名后的cookie值为 s%3Achyingp.uVofnk6k%2B9mHQpdPlQeOfjM8B5oa6mppny9d%2BmG9rD0 ,decode后为 s:chyingp.uVofnk6k+9mHQpdPlQeOfjM8B5oa6mppny9d+mG9rD0

下面就来分析下,cookie的签名、解析是如何实现的。

cookie签名、验证实现剖析

Express完成cookie值的签名, cookie-parser 实现签名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);
}

这里的 secret 哪来的呢?是 cookie-parser 初始化的时候传入的。如下伪代码所示:

var cookieParser = function (secret) {
 return function (req, res, next) {
  req.secret = secret;
  // ...
  next();
 };
};
app.use(cookieParser('secret'));

签名cookie解析

知道了cookie签名的机制后,如何"解析"签名cookie就很清楚了。这个阶段,中间件主要做了两件事:

  1. 将签名cookie对应的原始值提取出来

  2. 验证签名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;
}

判断、提取cookie原始值比较简单。只是是 unsign 方法名比较有迷惑性。

一般只会对签名进行合法校验,并没有所谓的反签名。

unsign 方法的代码如下:

  1. 首先,从传入的cookie值中,分别提取出原始值A1、签名值B1。

  2. 其次,用同样的秘钥对A1进行签名,得到A2。

  3. 最后,根据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被篡改 ,增强安全性。

举个小例子来看下cookie签名是如何实现防篡改的。

基于前面的例子展开。假设网站通过 nick 这个cookie来区分当前登录的用户是谁。在前面例子中,登录用户的cookie中,nick对应的值如下:(decode后的)

s:chyingp.uVofnk6k+9mHQpdPlQeOfjM8B5oa6mppny9d+mG9rD0

此时,有人试图修改这个cookie值,来达到伪造身份的目的。比如修改成 xiaoming :

s:xiaoming.uVofnk6k+9mHQpdPlQeOfjM8B5oa6mppny9d+mG9rD0

当网站收到请求,对签名cookie进行解析,发现签名验证不通过。由此可判断,cookie是伪造的。

hmac("xiaoming", "secret") !== "uVofnk6k+9mHQpdPlQeOfjM8B5oa6mppny9d+mG9rD0"

쿠키 서명과 구문 분석이 어떻게 구현되는지 분석해 보겠습니다.

쿠키 서명 분석 및 검증 구현

Express는 쿠키 값의 서명을 완성하고, cookie-parser는 서명된 쿠키의 구문 분석을 구현합니다. 둘 다 동일한 비밀 키를 공유합니다. 🎜🎜🎜쿠키 서명🎜🎜🎜Express의 쿠키 설정(서명 포함)은 모두 res.cookie() 메서드를 통해 구현됩니다. 🎜🎜간략화된 코드는 다음과 같습니다. 🎜rrreee🎜sign은 서명 기능입니다. 의사 코드는 다음과 같으며 실제로 쿠키의 원래 값과 hmac 뒤의 값을 연결합니다. 🎜🎜칠판을 두드려 강조 표시하세요. 서명된 쿠키 값에는 원래 값이 포함됩니다. 🎜rrreee🎜여기 비밀은 어디서 나오는 걸까요? cookie-parser 가 초기화될 때 전달됩니다. 다음 의사 코드에 표시된 대로: 🎜rrreee🎜🎜서명된 쿠키 구문 분석🎜🎜🎜쿠키 서명 메커니즘을 알고 나면 서명된 쿠키를 "파싱"하는 방법이 분명해집니다. 이 단계에서 미들웨어는 주로 두 가지 작업을 수행합니다. 🎜🎜🎜🎜서명된 쿠키에 해당하는 원래 값을 추출합니다. 🎜🎜🎜🎜서명된 쿠키가 합법적인지 확인합니다. 🎜🎜🎜🎜구현 코드는 다음과 같습니다. 🎜rrreee🎜Judge 쿠키의 원래 값을 추출합니다. 값은 비교적 간단합니다. 단지 unsign 메소드의 이름이 혼란스러울 뿐입니다. 🎜🎜일반적으로 서명은 법적으로 확인만 되며 소위 연대서명은 없습니다. 🎜🎜unsign 메소드의 코드는 다음과 같습니다. 🎜🎜🎜🎜먼저, 들어오는 쿠키 값에서 원래 값 A1과 서명 값 B1을 추출합니다. 🎜🎜🎜🎜둘째, 동일한 비밀 키를 사용하여 A1에 서명하여 A2를 얻습니다. 🎜🎜🎜🎜마지막으로 A2와 B1이 동일한지 여부에 따라 서명이 적법한지 여부를 판단합니다. 🎜🎜🎜🎜exports.unsign = function(val, secret){🎜rrreee🎜🎜🎜쿠키 서명의 역할🎜🎜🎜🎜은 주로 보안상의 이유로 쿠키가 변조되는 것을 방지하고 보안을 강화하는 것입니다. 🎜🎜 쿠키 서명이 어떻게 변조를 방지할 수 있는지 간단한 예를 들어 보겠습니다. 🎜🎜이전 예시를 토대로 확장해 보세요. 웹사이트가 현재 로그인한 사용자가 누구인지 구별하기 위해 닉 쿠키를 사용한다고 가정합니다. 이전 예에서 로그인한 사용자의 쿠키에서 nick에 해당하는 값은 다음과 같습니다. (디코딩 후)🎜🎜s:chyingp.uVofnk6k+9mHQpdPlQeOfjM8B5oa6mppny9d+mG9rD0🎜🎜이에 이때 누군가가 신원 위조 목적을 달성하기 위해 이 쿠키 값을 수정하려고 시도했습니다. 예를 들어, 이를 Xiaoming으로 변경합니다: 🎜🎜s:xiaoming.uVofnk6k+9mHQpdPlQeOfjM8B5oa6mppny9d+mG9rD0🎜🎜웹사이트가 요청을 받으면 서명 쿠키를 구문 분석하여 서명 확인에 실패했음을 확인합니다. 이를 통해 쿠키가 위조된 것으로 판단할 수 있습니다. 🎜🎜hmac("xiaoming", "secret") !== "uVofnk6k+9mHQpdPlQeOfjM8B5oa6mppny9d+mG9rD0"🎜🎜🎜🎜서명으로 보안이 보장되는 것은 아닌가요? 🎜

이전 섹션의 예에서는 로그인한 사용자를 확인하기 위해 닉 쿠키 값만 사용합니다. 이는 매우 나쁜 디자인입니다. 비밀 키를 알 수 없는 경우 서명된 쿠키를 위조하는 것은 어렵습니다. 그러나 사용자 이름이 동일하면 서명도 동일합니다. 이 경우 실제로 위조가 매우 쉽습니다.

위 내용은 모두를 위해 제가 정리한 내용입니다. 앞으로 모든 사람에게 도움이 되기를 바랍니다.

관련 기사:

Vue 구성 요소 통신(자세한 튜토리얼)

Vue Socket.io 소스 코드에 대한 자세한 분석

네이티브 JavaScript를 사용하여 돋보기 효과 얻기

위 내용은 Express에서 쿠키 파서 미들웨어를 사용하는 방법의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.