前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >cookie-parser项目源码阅读

cookie-parser项目源码阅读

作者头像
用户1515472
发布2019-07-25 17:02:02
6680
发布2019-07-25 17:02:02
举报

cookie-parser相信使用过Express的人肯定使用过,cookie-parser是一个Express解析cookie的中间件,其中关于signed cookie的疑问可以在 What are “signed” cookies in connect/expressjs?这里找到。(等我智商涨一点再来看了)。 req本质是inComingMessage,cookie-parser所做的工作是将cookie从header中转移到req中,并且转化为json对象。

大神片段:

var secrets = !secret || Array.isArray(secret)
            ? (secret || [])
            : [secret]

作用是:将字符串、空值、数组都转化为数组

/*!
 * 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
}
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 大神片段:
相关产品与服务
消息队列 TDMQ
消息队列 TDMQ (Tencent Distributed Message Queue)是腾讯基于 Apache Pulsar 自研的一个云原生消息中间件系列,其中包含兼容Pulsar、RabbitMQ、RocketMQ 等协议的消息队列子产品,得益于其底层计算与存储分离的架构,TDMQ 具备良好的弹性伸缩以及故障恢复能力。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档