
RFC6265를 준수하는 쿠키 파싱 및 CookieJar 관리 라이브러리로, Node.js용이며 CVE-2023-26136 보안 패치가 적용되었습니다. HTTP 클라이언트를 위한 쿠키 생성, 검증, 저장 및 검색을 지원합니다.
RFC6265 Node.js용 쿠키 및 CookieJar
var tough = require('tough-cookie'); var Cookie = tough.Cookie; var cookie = Cookie.parse(header); cookie.value = 'somethingdifferent'; header = cookie.toString();
var cookiejar = new tough.CookieJar(); cookiejar.setCookie(cookie, 'http://currentdomain.example.com/path', cb); // ... cookiejar.getCookies('http://example.com/otherpath',function(err,cookies) { res.headers['cookie'] = cookies.join('; '); });
# 설치
정말 _쉽습니다_!
`npm install tough-cookie`
왜 이런 이름일까요? NPM 모듈 `cookie`, `cookies`, `cookiejar`는 이미 사용 중이었습니다.
## 버전 지원
node.js 버전 지원은 [request](https://www.npmjs.com/package/request) 모듈의 지원을 따릅니다.
# API
## tough
`require('tough-cookie')`로 가져오는 모듈의 함수들입니다. 모두 순수 함수로 사용할 수 있으며 "바인딩"할 필요가 없습니다.
**참고**: 1.0.x 이전에는 여러 함수들이 `strict` 매개변수를 받았습니다. 이후 더 이상 필요하지 않게 되어 API에서 제거되었습니다.
### `parseDate(string)`
쿠키 날짜 문자열을 `Date`로 파싱합니다. `Date.parse()`가 아닌 RFC6265 5.1.1절에 따라 파싱합니다.
### `formatDate(date)`
Date를 RFC1123 문자열로 포맷합니다 (RFC6265에서 권장하는 형식).
### `canonicalDomain(str)`
도메인 이름을 정식 도메인 이름으로 변환합니다. 정식 도메인 이름은 공백 제거, 소문자 변환, 선행 점 제거 및 선택적으로 punycode 인코딩된 도메인 이름입니다 (RFC6265 5.1.2절). 대부분의 경우 이 함수는 멱등적입니다 (출력에 다시 실행해도 부작용이 없습니다).
### `domainMatch(str,domStr[,canonicalize=true])`
실제 도메인이 쿠키의 도메인과 일치하는지 여부를 답합니다. `str`은 "현재" 도메인 이름이고 `domStr`은 "쿠키" 도메인 이름입니다. RFC6265 5.1.3절에 따라 일치하지만, "접미사 일치"로 생각하면 도움이 됩니다.
`canonicalize` 매개변수는 다른 두 매개변수를 `canonicalDomain`에 통과시킬지 여부를 결정합니다.
### `defaultPath(path)`
현재 요청/응답 경로가 주어지면 쿠키에 저장하기 적합한 Path를 반환합니다. 기본적으로 경로에서 "파일"의 "디렉토리"이지만, RFC 5.1.4절에 의해 지정됩니다.
`path` 매개변수는 URI의 _경로명_ 부분만 있어야 합니다 (즉, 호스트명, 쿼리, 프래그먼트 등은 제외). 이는 node의 `uri.parse()` 출력의 `.pathname` 속성입니다.
### `pathMatch(reqPath,cookiePath)`
RFC6265 5.1.4절에 따라 요청 경로가 주어진 쿠키 경로와 경로 일치하는지 여부를 답합니다. 불리언을 반환합니다.
이는 기본적으로 `cookiePath`가 `reqPath`의 접두사인 접두사 일치입니다.
### `parse(cookieString[, options])`
`Cookie.parse(cookieString[, options])`의 별칭입니다.
### `fromJSON(string)`
`Cookie.fromJSON(string)`의 별칭입니다.
### `getPublicSuffix(hostname)`
이 호스트명의 공개 접미사를 반환합니다. 공개 접미사는 쿠키를 설정할 수 있는 가장 짧은 도메인 이름입니다. 해당 호스트명에 쿠키를 설정할 수 없으면 `null`을 반환합니다.
예: `www.example.com`과 `www.subdomain.example.com` 모두 공개 접미사가 `example.com`입니다.
자세한 내용은 http://publicsuffix.org/를 참조하세요. 이 모듈은 해당 사이트에서 목록을 가져옵니다. 이 호출은 현재 [`psl`](https://www.npmjs.com/package/psl)의 [get() 메서드](https://www.npmjs.com/package/psl#pslgetdomain)를 래핑한 것입니다.
### `cookieCompare(a,b)`
`.sort()`와 함께 사용하여 쿠키 목록을 RFC에서 권장하는 순서(5.4절 2단계)로 정렬합니다. 정렬 알고리즘은 우선순위 순서대로 다음과 같습니다:
* 가장 긴 `.path`
* 가장 오래된 `.creation` (1ms 정밀도, `Date`와 동일)
* 가장 낮은 `.creationIndex` (1ms 정밀도를 넘어서기 위해)``` javascript
var cookies = [ /* unsorted array of Cookie objects */ ];
cookies = cookies.sort(cookieCompare);
참고: JavaScript의 Date는 1ms 정밀도로 제한되어 있으므로, 동일한 밀리초 내에 쿠키가 생성되는 것은 완전히 가능합니다. 이는 .setCookie()에 now 옵션을 사용할 때 특히 그렇습니다. .creationIndex 속성은 프로세스별 전역 카운터로, new Cookie()로 생성 시 할당됩니다. 이는 RFC 정렬의 정신을 유지합니다: 오래된 쿠키가 먼저 옵니다. 이는 MemoryCookieStore에서 잘 작동합니다. Set-Cookie 헤더가 순서대로 파싱되기 때문입니다. 하지만 분산 시스템에서는 그렇게 좋지 않을 수 있습니다. 정교한 Store는 다른 _논리적 시계_로 설정하여, 쿠키 A와 B가 같은 밀리초에 생성되었지만 쿠키 A가 쿠키 B보다 먼저 생성된 경우 A.creationIndex < B.creationIndex가 되도록 할 수 있습니다. 전역 카운터를 변경하려면(아마도 하지 말아야 할 일이지만), Cookie.cookiesCreated에 저장되어 있습니다.
permuteDomain(domain)domainMatch() 매개변수와 일치하는 모든 가능한 도메인 목록을 생성합니다. 쿠키 저장소 구현에 유용할 수 있습니다.
permutePath(path)pathMatch() 매개변수와 일치하는 모든 가능한 경로 목록을 생성합니다. 쿠키 저장소 구현에 유용할 수 있습니다.
tough.Cookie를 통해 내보내집니다.
Cookie.parse(cookieString[, options])단일 Cookie 또는 Set-Cookie HTTP 헤더를 파싱하여 Cookie 객체로 만듭니다. 문자열을 파싱할 수 없으면 undefined를 반환합니다.
options 매개변수는 필수가 아니며 현재 한 가지 속성만 있습니다:
true이면 =abc 및 =와 같은 키 없는 쿠키의 파싱을 활성화합니다. 이는 RFC를 준수하지 않습니다.options가 객체가 아니면 무시됩니다. 즉, Array#map과 함께 사용할 수 있습니다.
다음은 Node HTTP/HTTPS 응답에서 Set-Cookie 헤더를 처리하는 방법입니다:``` javascript if (res.headers['set-cookie'] instanceof Array) cookies = res.headers['set-cookie'].map(Cookie.parse); else cookies = [Cookie.parse(res.headers['set-cookie'])];
_Note:_ in version 2.3.3, tough-cookie limited the number of spaces before the `=` to 256 characters. This limitation has since been removed.
See [Issue 92](https://github.com/salesforce/tough-cookie/issues/92)
### 속성
Cookie 객체 속성:
* _key_ - string - 쿠키의 이름 또는 키 (기본값 "")
* _value_ - string - 쿠키의 값 (기본값 "")
* _expires_ - `Date` - 설정된 경우 쿠키의 `Expires=` 속성 (기본값은 문자열 `"Infinity"`). `setExpires()` 참조
* _maxAge_ - 초 - 설정된 경우 쿠키의 (초 단위) `Max-Age=` 속성. 만료 없음 및 즉시 만료를 위해 각각 문자열 `"Infinity"` 및 `"-Infinity"`로 설정할 수도 있습니다. `setMaxAge()` 참조
* _domain_ - string - 쿠키의 `Domain=` 속성
* _path_ - string - 쿠키의 `Path=` 속성
* _secure_ - boolean - `Secure` 쿠키 플래그
* _httpOnly_ - boolean - `HttpOnly` 쿠키 플래그
* _extensions_ - `Array` - 인식되지 않은 쿠키 속성 (내부에 등호가 있어도 문자열)
* _creation_ - `Date` - 이 쿠키가 생성된 시간
* _creationIndex_ - 숫자 - 생성 시 설정되며, 더 정확한 정렬을 위해 사용됩니다 (자세한 설명은 `cookieCompare(a,b)` 참조)
`CookieJar.setCookie()`를 통해 쿠키가 전달된 후에는 다음과 같은 추가 속성이 생깁니다:
* _hostOnly_ - boolean - 호스트 전용 쿠키인지 여부 (즉, Domain 필드가 설정되지 않았지만 암시됨)
* _pathIsDefault_ - boolean - true인 경우 쿠키에 Path 필드가 없었고 `defaultPath()`를 사용하여 하나를 도출했습니다.
* _creation_ - `Date` - 생성 시점에서 쿠키가 jar에 추가된 시점으로 **수정됨**
* _lastAccessed_ - `Date` - 쿠키가 마지막으로 액세스된 시간. 구현되면 쿠키 정리에 영향을 미칩니다. `cookiejar.getCookies(...)`를 사용하면 이 속성이 업데이트됩니다.
### `Cookie([{properties}])`
속성 객체를 받아서 위의 Cookie 속성 중 어떤 것이든 포함할 수 있으며, 지정되지 않은 속성에는 기본값을 사용합니다.
### `.toString()`
Set-Cookie 헤더 값으로 인코딩합니다. Expires 쿠키 필드는 `formatDate()`를 사용하여 설정되지만 `.expires`가 `Infinity`인 경우 완전히 생략됩니다.
### `.cookieString()`
Cookie 헤더 값으로 인코딩합니다 (즉, `.key`와 `.value` 속성이 '='로 결합됨).
### `.setExpires(String)`
`parseDate()`를 통해 전달된 날짜 문자열을 기반으로 만료를 설정합니다. parseDate가 `null`을 반환하면 (즉, 이 날짜 문자열을 구문 분석할 수 없음) `.expires`가 `"Infinity"` (문자열)로 설정됩니다.
### `.setMaxAge(number)`
maxAge를 초 단위로 설정합니다. `-Infinity`를 `"-Infinity"`로, `Infinity`를 `"Infinity"`로 강제 변환하여 JSON 직렬화가 올바르게 작동하도록 합니다.
### `.expiryTime([now=Date.now()])`
### `.expiryDate([now=Date.now()])`
expiryTime()은 이 쿠키가 만료되는 절대 unix epoch 밀리초를 계산합니다. expiryDate()도 유사하게 작동하지만 `Date` 객체를 반환합니다. 두 경우 모두 `now` 매개변수는 밀리초여야 합니다.
Max-Age는 Expires보다 우선합니다 (RFC에 따라). `.creation` 속성 (또는 기본적으로 `now` 매개변수)이 `.maxAge` 속성을 오프셋하는 데 사용됩니다.
Expires (`.expires`)가 설정된 경우 해당 값이 반환됩니다.
그렇지 않으면 `expiryTime()`은 `Infinity`를 반환하고 `expiryDate()`는 "Tue, 19 Jan 2038 03:14:07 GMT"에 대한 `Date` 객체를 반환합니다 (32비트 `time_t`로 표현할 수 있는 가장 늦은 날짜; 대부분의 사용자 에이전트의 일반적인 제한).
### `.TTL([now=Date.now()])`
`now` (밀리초)를 기준으로 TTL을 계산합니다. `expiryTime`/`expiryDate`와 동일한 우선 순위 규칙이 적용됩니다.
명시적인 만료가 없는 쿠키의 경우 "숫자" `Infinity`가 반환되고, 쿠키가 만료된 경우 `0`이 반환됩니다. 그렇지 않으면 밀리초 단위의 TTL이 반환됩니다.
### `.canonicalizedDomain()`
### `.cdomain()`
정규화된 `.domain` 필드를 반환합니다. 도메인에 ASCII가 아닌 문자가 있는 경우 소문자로 변환되고 punycode (RFC3490)로 인코딩됩니다.
### `.toJSON()`
`JSON.serialize(cookie)`를 사용할 때 편리합니다. JSON 직렬화할 수 있는 일반 `Object`를 반환합니다.
모든 `Date` 속성 (즉, `.expires`, `.creation`, `.lastAccessed`)은 ISO 형식 (`.toISOString()`)으로 내보내집니다.
**참고**: 사용자 정의 `Cookie` 속성은 버려집니다. tough-cookie 1.x에서는 `.toJSON` 메서드가 명시적으로 정의되지 않았기 때문에 열거 가능한 모든 속성이 캡처되었습니다. 속성을 직렬화하려면 속성 이름을 `Cookie.serializableProperties` 배열에 추가하세요.
### `Cookie.fromJSON(strOrObj)`
`cookie.toJSON()`의 역을 수행합니다. 문자열이 전달되면 먼저 `JSON.parse()`를 수행합니다.
모든 `Date` 속성 (즉, `.expires`, `.creation`, `.lastAccessed`)은 `Date.parse()`를 통해 구문 분석됩니다. tough-cookie의 `parseDate`가 아닙니다. 이 레이어에서는 JavaScript/JSON 스타일 타임스탬프가 처리되기 때문입니다.
JSON 구문 분석 오류가 발생하면 `null`을 반환합니다.
### `.clone()`
이 쿠키의 깊은 복제를 수행하며, 정확히 `Cookie.fromJSON(cookie.toJSON())`으로 구현됩니다.
### `.validate()`