1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
9 |
|
10 |
|
11 | var cookieParser = require('cookie-parser');
|
12 | var parseUrl = require('parseurl');
|
13 | var Cookie = require('express-session').Cookie
|
14 | , debug = require('debug')('connect:cookieSession')
|
15 | , signature = require('cookie-signature')
|
16 | , onHeaders = require('on-headers')
|
17 | , url = require('url');
|
18 |
|
19 |
|
20 |
|
21 |
|
22 |
|
23 |
|
24 |
|
25 |
|
26 |
|
27 |
|
28 |
|
29 |
|
30 |
|
31 |
|
32 |
|
33 |
|
34 |
|
35 |
|
36 |
|
37 |
|
38 |
|
39 |
|
40 |
|
41 |
|
42 |
|
43 |
|
44 |
|
45 |
|
46 |
|
47 |
|
48 |
|
49 |
|
50 |
|
51 |
|
52 | module.exports = function cookieSession(options){
|
53 |
|
54 | options = options || {};
|
55 | var key = options.key || 'connect.sess'
|
56 | , trustProxy = options.proxy;
|
57 |
|
58 | return function cookieSession(req, res, next) {
|
59 |
|
60 |
|
61 | var secret = options.secret || req.secret;
|
62 | if (!secret) throw new Error('`secret` option required for cookie sessions');
|
63 |
|
64 |
|
65 | req.session = {};
|
66 | var cookie = req.session.cookie = new Cookie(options.cookie);
|
67 |
|
68 |
|
69 | var originalPath = parseUrl.original(req).pathname;
|
70 | if (0 != originalPath.indexOf(cookie.path)) return next();
|
71 |
|
72 |
|
73 | if (!options.secret && req.secret) {
|
74 | req.session = req.signedCookies[key] || {};
|
75 | req.session.cookie = cookie;
|
76 | } else {
|
77 |
|
78 | var rawCookie = req.cookies[key];
|
79 | if (rawCookie) {
|
80 | var unsigned = cookieParser.signedCookie(rawCookie, secret);
|
81 | if (unsigned) {
|
82 | var original = unsigned;
|
83 | req.session = cookieParser.JSONCookie(unsigned) || {};
|
84 | req.session.cookie = cookie;
|
85 | }
|
86 | }
|
87 | }
|
88 |
|
89 | onHeaders(res, function(){
|
90 |
|
91 | if (!req.session) {
|
92 | debug('clear session');
|
93 | cookie.expires = new Date(0);
|
94 | res.setHeader('Set-Cookie', cookie.serialize(key, ''));
|
95 | return;
|
96 | }
|
97 |
|
98 | delete req.session.cookie;
|
99 |
|
100 |
|
101 | var proto = (req.headers['x-forwarded-proto'] || '').toLowerCase()
|
102 | , tls = req.connection.encrypted || (trustProxy && 'https' == proto.split(/\s*,\s*/)[0]);
|
103 |
|
104 |
|
105 | if (cookie.secure && !tls) return debug('not secured');
|
106 |
|
107 |
|
108 | debug('serializing %j', req.session);
|
109 | var val = 'j:' + JSON.stringify(req.session);
|
110 |
|
111 |
|
112 | if (original == val) return debug('unmodified session');
|
113 |
|
114 |
|
115 | val = 's:' + signature.sign(val, secret);
|
116 | val = cookie.serialize(key, val);
|
117 | debug('set-cookie %j', cookie);
|
118 | res.setHeader('Set-Cookie', val);
|
119 | });
|
120 |
|
121 | next();
|
122 | };
|
123 | };
|