cookie-parser相信使用过Express的人肯定使用过,cookie-parser是一个Express解析cookie的中间件,其中关于signed cookie的疑问可以在 What are “signed” cookies in connect/expressjs?这里找到。(等我智商涨一点再来看了)。 req本质是inComingMessage,cookie-parser所做的工作是将cookie从header中转移到req中,并且转化为json对象。
大神片段:
代码语言:javascript复制var secrets = !secret || Array.isArray(secret)
? (secret || [])
: [secret]
作用是:将字符串、空值、数组都转化为数组
代码语言:javascript复制/*!
* cookie-parser
* Copyright(c) 2014 TJ Holowaychuk
* Copyright(c) 2015 Douglas Christopher Wilson
* MIT Licensed
*/
'use strict'
/**
* Module dependencies.
* @private
*/
var cookie = require('cookie')
var signature = require('cookie-signature')
/**
* Module exports.
* @public
*/
module.exports = cookieParser
module.exports.JSONCookie = JSONCookie
module.exports.JSONCookies = JSONCookies
module.exports.signedCookie = signedCookie
module.exports.signedCookies = signedCookies
/**
* Parse Cookie header and populate `req.cookies`
* with an object keyed by the cookie names.
*
* @param {string|array} [secret] A string (or array of strings) representing cookie signing secret(s).
* @param {Object} [options]
* @return {Function}
* @public
*/
function cookieParser (secret, options) {
return function cookieParser (req, res, next) {
// 如果cookies已经存储在req对象中,则直接跳过
if (req.cookies) {
return next()
}
// req本质是inComingMessage,cookie存在headers中
var cookies = req.headers.cookie
// secret可以为空,字符串,或者数组,全部转化为数组
var secrets = !secret || Array.isArray(secret)
? (secret || [])
: [secret]
req.secret = secrets[0]
// 普通cookie对象
req.cookies = Object.create(null)
// signed cookie对象
req.signedCookies = Object.create(null)
// no cookies
if (!cookies) {
return next()
}
// 利用cookie模块将其解析为json对象
req.cookies = cookie.parse(cookies, options)
// parse signed cookies
if (secrets.length !== 0) {
req.signedCookies = signedCookies(req.cookies, secrets)
req.signedCookies = JSONCookies(req.signedCookies)
}
// parse JSON cookies
req.cookies = JSONCookies(req.cookies)
next()
}
}
/**
* Parse JSON cookie string.
*
* @param {String} str
* @return {Object} Parsed object or undefined if not json cookie
* @public
*/
function JSONCookie (str) {
if (typeof str !== 'string' || str.substr(0, 2) !== 'j:') {
return undefined
}
try {
return JSON.parse(str.slice(2))
} catch (err) {
return undefined
}
}
/**
* Parse JSON cookies.
*
* @param {Object} obj
* @return {Object}
* @public
*/
function JSONCookies (obj) {
var cookies = Object.keys(obj)
var key
var val
for (var i = 0; i < cookies.length; i ) {
key = cookies[i]
val = JSONCookie(obj[key])
if (val) {
obj[key] = val
}
}
return obj
}
/**
* Parse a signed cookie string, return the decoded value.
*
* @param {String} str signed cookie string
* @param {string|array} secret
* @return {String} decoded value
* @public
*/
function signedCookie (str, secret) {
if (typeof str !== 'string') {
return undefined
}
if (str.substr(0, 2) !== 's:') {
return str
}
var secrets = !secret || Array.isArray(secret)
? (secret || [])
: [secret]
for (var i = 0; i < secrets.length; i ) {
var val = signature.unsign(str.slice(2), secrets[i])
if (val !== false) {
return val
}
}
return false
}
/**
* Parse signed cookies, returning an object containing the decoded key/value
* pairs, while removing the signed key from obj.
*
* @param {Object} obj
* @param {string|array} secret
* @return {Object}
* @public
*/
function signedCookies (obj, secret) {
// 获取cookie的所有键名为数组
var cookies = Object.keys(obj)
var dec
var key
var ret = Object.create(null)
var val
for (var i = 0; i < cookies.length; i ) {
// 键
key = cookies[i]
// 值
val = obj[key]
dec = signedCookie(val, secret)
if (val !== dec) {
ret[key] = dec
delete obj[key]
}
}
return ret
}