mm_session 1.5.1 → 1.5.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +298 -0
- package/README_EN.md +296 -0
- package/eslint.config.js +3 -4
- package/index.js +4 -3
- package/lib/helper.js +99 -0
- package/lib/session.js +335 -120
- package/lib/store.js +15 -44
- package/package.json +5 -6
- package/test.js +287 -149
package/lib/store.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
const {
|
|
1
|
+
const { Cache } = require('mm_cache');
|
|
2
2
|
|
|
3
3
|
if (!$.cache) {
|
|
4
|
-
$.cache = new
|
|
4
|
+
$.cache = new Cache();
|
|
5
5
|
}
|
|
6
6
|
|
|
7
7
|
/**
|
|
@@ -21,34 +21,17 @@ class Store {
|
|
|
21
21
|
}
|
|
22
22
|
}
|
|
23
23
|
|
|
24
|
-
/**
|
|
25
|
-
* 获取session ID
|
|
26
|
-
* @param {object} ctx HTTP上下文
|
|
27
|
-
* @returns {string} session ID
|
|
28
|
-
*/
|
|
29
|
-
Store.prototype.getID = async function(ctx) {
|
|
30
|
-
var header = ctx.request.header;
|
|
31
|
-
var user_agent = header['user-agent'];
|
|
32
|
-
if (!user_agent) {
|
|
33
|
-
user_agent = 'mm';
|
|
34
|
-
}
|
|
35
|
-
var start_hash = user_agent.md5().substring(0, 32);
|
|
36
|
-
var time_stamp = Date.parse(new Date()) / 1000;
|
|
37
|
-
var uuid = (ctx.ip + '_' + time_stamp).aes_encode(start_hash);
|
|
38
|
-
return uuid;
|
|
39
|
-
};
|
|
40
|
-
|
|
41
24
|
/**
|
|
42
25
|
* 获取session缓存
|
|
43
26
|
* @param {string} uuid 客户端唯一ID
|
|
44
27
|
* @returns {object|null} session对象或null
|
|
45
28
|
*/
|
|
46
|
-
Store.prototype.get = async function(uuid) {
|
|
29
|
+
Store.prototype.get = async function (uuid) {
|
|
47
30
|
if (!$.cache.has(this.key + uuid)) return undefined;
|
|
48
31
|
// 我们正在解码数据来自我们的srote, 我们假定它是在储存之前
|
|
49
32
|
var val = await $.cache.get(this.key + uuid);
|
|
50
33
|
if (val) {
|
|
51
|
-
if (typeof(val) == 'string') {
|
|
34
|
+
if (typeof (val) == 'string') {
|
|
52
35
|
return JSON.parse(val);
|
|
53
36
|
}
|
|
54
37
|
return val;
|
|
@@ -59,44 +42,32 @@ Store.prototype.get = async function(uuid) {
|
|
|
59
42
|
|
|
60
43
|
/**
|
|
61
44
|
* 设置session到缓存
|
|
45
|
+
* @param {string} uuid session ID
|
|
62
46
|
* @param {object} session session对象
|
|
63
|
-
* @param {
|
|
64
|
-
* @param {string} options.uuid 客户端唯一表示ID
|
|
65
|
-
* @param {number} options.max_age 最大寿命
|
|
66
|
-
* @param {object} ctx HTTP请求上下文
|
|
47
|
+
* @param {number} max_age 最大寿命(秒)
|
|
67
48
|
* @returns {string} session ID
|
|
68
49
|
*/
|
|
69
|
-
Store.prototype.set = async function(session, {
|
|
70
|
-
uuid,
|
|
71
|
-
max_age
|
|
72
|
-
} = {}, ctx) {
|
|
73
|
-
let session_uuid = uuid;
|
|
74
|
-
let session_max_age = max_age;
|
|
75
|
-
|
|
76
|
-
if (!session_uuid) {
|
|
77
|
-
session_uuid = await this.getID(ctx);
|
|
78
|
-
}
|
|
79
|
-
if (!session_max_age) {
|
|
80
|
-
session_max_age = 7200;
|
|
81
|
-
}
|
|
82
|
-
|
|
50
|
+
Store.prototype.set = async function (uuid, session, max_age = 7200) {
|
|
83
51
|
let session_str = session;
|
|
84
52
|
try {
|
|
85
|
-
|
|
53
|
+
console.log(' - Store.set接收到的session对象:', session);
|
|
54
|
+
if (typeof (session_str) == 'object') {
|
|
86
55
|
session_str = JSON.stringify(session_str);
|
|
56
|
+
console.log(' - JSON序列化后的session:', session_str);
|
|
87
57
|
}
|
|
88
|
-
|
|
58
|
+
|
|
59
|
+
await $.cache.set(this.key + uuid, session_str, max_age);
|
|
89
60
|
} catch (err) {
|
|
90
61
|
$.log.debug('Set session error:', err);
|
|
91
62
|
}
|
|
92
|
-
return
|
|
63
|
+
return uuid;
|
|
93
64
|
};
|
|
94
65
|
|
|
95
66
|
/**
|
|
96
|
-
*
|
|
67
|
+
* 删除缓存
|
|
97
68
|
* @param {string} uuid 客户端唯一ID
|
|
98
69
|
*/
|
|
99
|
-
Store.prototype.
|
|
70
|
+
Store.prototype.del = function (uuid) {
|
|
100
71
|
$.cache.del(this.key + uuid);
|
|
101
72
|
};
|
|
102
73
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mm_session",
|
|
3
|
-
"version": "1.5.
|
|
3
|
+
"version": "1.5.3",
|
|
4
4
|
"description": "这是超级美眉session函数模块,用于web服务端session缓存",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -29,12 +29,11 @@
|
|
|
29
29
|
"url": "https://gitee.com/qiuwenwu91/mm_session/issues"
|
|
30
30
|
},
|
|
31
31
|
"homepage": "https://gitee.com/qiuwenwu91/mm_session#readme",
|
|
32
|
-
"dependencies": {
|
|
33
|
-
"mm_cachebase": "^1.9.2"
|
|
34
|
-
},
|
|
35
32
|
"devDependencies": {
|
|
36
33
|
"eslint-plugin-jsdoc": "^61.5.0",
|
|
37
|
-
"
|
|
38
|
-
|
|
34
|
+
"mm_eslint": "^1.0.8"
|
|
35
|
+
},
|
|
36
|
+
"dependencies": {
|
|
37
|
+
"mm_cache": "^1.4.7"
|
|
39
38
|
}
|
|
40
39
|
}
|
package/test.js
CHANGED
|
@@ -1,190 +1,328 @@
|
|
|
1
|
-
|
|
1
|
+
'use strict';
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
// 简单的AES编码模拟
|
|
5
|
-
return Buffer.from(this).toString('base64') + '_' + key.substring(0, 8);
|
|
6
|
-
};
|
|
3
|
+
const { session, Session, Store } = require('./index.js');
|
|
7
4
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
use(middleware) {
|
|
15
|
-
this.middlewares.push(middleware);
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
async handleRequest(ctx) {
|
|
19
|
-
// 执行中间件链
|
|
20
|
-
const executeMiddleware = async (index) => {
|
|
21
|
-
if (index < this.middlewares.length) {
|
|
22
|
-
const middleware = this.middlewares[index];
|
|
23
|
-
await middleware(ctx, () => executeMiddleware(index + 1));
|
|
24
|
-
}
|
|
25
|
-
};
|
|
26
|
-
|
|
27
|
-
await executeMiddleware(0);
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
// 模拟Koa的上下文对象
|
|
5
|
+
/**
|
|
6
|
+
* 模拟Koa上下文对象
|
|
7
|
+
* @class MockContext
|
|
8
|
+
* @param {object} headers HTTP请求头
|
|
9
|
+
* @param {object} cookies cookie数据
|
|
10
|
+
*/
|
|
32
11
|
class MockContext {
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
12
|
+
/**
|
|
13
|
+
* 构造函数
|
|
14
|
+
* @param {object} headers HTTP请求头
|
|
15
|
+
* @param {object} cookies cookie数据
|
|
16
|
+
*/
|
|
17
|
+
constructor(headers = {}, cookies = {}) {
|
|
18
|
+
this.headers = headers;
|
|
19
|
+
this._cookies = cookies;
|
|
36
20
|
this.ip = '127.0.0.1';
|
|
37
|
-
this.
|
|
38
|
-
|
|
39
|
-
|
|
21
|
+
this.body = null;
|
|
22
|
+
this.status = null;
|
|
23
|
+
|
|
24
|
+
// 模拟cookies对象
|
|
25
|
+
this.cookies = {
|
|
26
|
+
get: (name) => {
|
|
27
|
+
return this._cookies[name] || null;
|
|
28
|
+
},
|
|
29
|
+
set: (name, value, options = {}) => {
|
|
30
|
+
this._cookies[name] = value;
|
|
40
31
|
}
|
|
41
32
|
};
|
|
42
|
-
this.session = null;
|
|
43
33
|
}
|
|
44
34
|
}
|
|
45
35
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
36
|
+
/**
|
|
37
|
+
* 模拟Koa next函数
|
|
38
|
+
* @returns {Promise<void>} 空Promise
|
|
39
|
+
*/
|
|
40
|
+
const mock_next = () => Promise.resolve();
|
|
51
41
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
42
|
+
/**
|
|
43
|
+
* 测试基本session中间件功能
|
|
44
|
+
* @returns {Promise<void>} 测试结果
|
|
45
|
+
*/
|
|
46
|
+
async function testBasicSession() {
|
|
47
|
+
console.log('1. 测试基本session中间件功能');
|
|
48
|
+
try {
|
|
49
|
+
const session_mw = session();
|
|
50
|
+
const ctx = new MockContext();
|
|
51
|
+
|
|
52
|
+
await session_mw(ctx, mock_next);
|
|
55
53
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
54
|
+
if (ctx.session) {
|
|
55
|
+
console.log('✓ session对象创建成功');
|
|
56
|
+
console.log('✓ session ID:', ctx.session.getId());
|
|
59
57
|
} else {
|
|
60
|
-
|
|
58
|
+
console.log('✗ session对象创建失败');
|
|
61
59
|
}
|
|
60
|
+
} catch (err) {
|
|
61
|
+
console.log('✗ 测试失败:', err.message);
|
|
62
62
|
}
|
|
63
63
|
}
|
|
64
64
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
65
|
+
/**
|
|
66
|
+
* 测试session数据读写功能
|
|
67
|
+
* @returns {Promise<void>} 测试结果
|
|
68
|
+
*/
|
|
69
|
+
async function testSessionDataRW() {
|
|
70
|
+
console.log('\n2. 测试session数据读写功能');
|
|
69
71
|
try {
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
72
|
+
const session_mw = session();
|
|
73
|
+
const ctx = new MockContext();
|
|
74
|
+
|
|
75
|
+
await session_mw(ctx, async () => {
|
|
76
|
+
// 在中间件中设置session数据
|
|
77
|
+
ctx.session.user_id = 123;
|
|
78
|
+
ctx.session.username = 'testuser';
|
|
79
|
+
ctx.session.is_logged_in = true;
|
|
75
80
|
});
|
|
76
|
-
console.log('✅ Session实例创建成功\n');
|
|
77
81
|
|
|
78
|
-
|
|
79
|
-
console.log('
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
82
|
+
console.log('✓ session数据设置成功');
|
|
83
|
+
console.log(' - user_id:', ctx.session.user_id);
|
|
84
|
+
console.log(' - username:', ctx.session.username);
|
|
85
|
+
console.log(' - is_logged_in:', ctx.session.is_logged_in);
|
|
86
|
+
} catch (err) {
|
|
87
|
+
console.log('✗ 测试失败:', err.message);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* 创建测试session
|
|
93
|
+
* @param {Function} session_mw session中间件
|
|
94
|
+
* @returns {Promise<object>} 包含session ID和上下文的对象
|
|
95
|
+
*/
|
|
96
|
+
async function createTestSession(session_mw) {
|
|
97
|
+
const ctx1 = new MockContext();
|
|
98
|
+
|
|
99
|
+
// 使用标准的中间件调用方式,确保保存逻辑被执行
|
|
100
|
+
await session_mw(ctx1, async () => {
|
|
101
|
+
// 在next()函数中设置session数据
|
|
102
|
+
ctx1.session.test_data = 'persistent_data';
|
|
103
|
+
// 强制标记session为已修改状态
|
|
104
|
+
ctx1.session._modified = true;
|
|
105
|
+
|
|
106
|
+
// 调试:检查session对象在设置数据后的状态
|
|
107
|
+
console.log(' - 第一次请求session对象状态:', {
|
|
108
|
+
uuid: ctx1.session.uuid,
|
|
109
|
+
test_data: ctx1.session.test_data,
|
|
110
|
+
_modified: ctx1.session._modified,
|
|
111
|
+
_is_new: ctx1.session._is_new
|
|
94
112
|
});
|
|
95
113
|
|
|
96
|
-
|
|
114
|
+
// 调试:检查session是否被标记为已修改
|
|
115
|
+
console.log(' - session._modified标志:', ctx1.session._modified);
|
|
116
|
+
});
|
|
97
117
|
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
118
|
+
// 调试:检查第一次请求后session是否被正确保存
|
|
119
|
+
console.log(' - 第一次请求后检查session._modified标志:', ctx1.session._modified);
|
|
120
|
+
|
|
121
|
+
const session_id = ctx1.session.getId();
|
|
122
|
+
console.log('✓ 第一次请求session ID:', session_id);
|
|
123
|
+
|
|
124
|
+
return { ctx1, session_id };
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* 验证session恢复结果
|
|
129
|
+
* @param {object} ctx2 第二次请求的上下文
|
|
130
|
+
* @param {string} session_id session ID
|
|
131
|
+
* @returns {Promise<boolean>} 恢复是否成功
|
|
132
|
+
*/
|
|
133
|
+
async function verifySessionRecover(ctx2, session_id) {
|
|
134
|
+
if (ctx2.session && ctx2.session.test_data === 'persistent_data') {
|
|
135
|
+
console.log('✓ session数据恢复成功');
|
|
136
|
+
return true;
|
|
137
|
+
} else {
|
|
138
|
+
console.log('✗ session数据恢复失败');
|
|
139
|
+
console.log(' - ctx2.session:', ctx2.session);
|
|
140
|
+
if (ctx2.session) {
|
|
141
|
+
console.log(' - test_data:', ctx2.session.test_data);
|
|
142
|
+
console.log(' - session ID是否匹配:', ctx2.session.uuid === session_id);
|
|
143
|
+
|
|
144
|
+
// 调试:直接检查存储中是否有数据
|
|
145
|
+
const store = new Store();
|
|
146
|
+
const stored_data = await store.get(session_id);
|
|
147
|
+
console.log(' - 存储中的数据:', stored_data);
|
|
148
|
+
|
|
149
|
+
// 调试:检查第一次请求后存储中的数据
|
|
150
|
+
const stored_data_first = await store.get(session_id);
|
|
151
|
+
console.log(' - 第一次请求后存储中的数据:', stored_data_first);
|
|
114
152
|
}
|
|
153
|
+
return false;
|
|
154
|
+
}
|
|
155
|
+
}
|
|
115
156
|
|
|
116
|
-
|
|
117
|
-
|
|
157
|
+
/**
|
|
158
|
+
* 测试从cookie中恢复session
|
|
159
|
+
* @returns {Promise<void>} 测试结果
|
|
160
|
+
*/
|
|
161
|
+
async function testSessionRecovery() {
|
|
162
|
+
console.log('\n3. 测试从cookie中恢复session');
|
|
163
|
+
try {
|
|
164
|
+
const session_mw = session();
|
|
118
165
|
|
|
119
|
-
//
|
|
120
|
-
const
|
|
121
|
-
if (sessionCookie) {
|
|
122
|
-
console.log('✅ session保存成功,cookie已设置');
|
|
123
|
-
console.log(' session ID:', sessionCookie);
|
|
124
|
-
} else {
|
|
125
|
-
console.log('⚠️ session保存但cookie未设置');
|
|
126
|
-
}
|
|
166
|
+
// 创建测试session
|
|
167
|
+
const { session_id } = await createTestSession(session_mw);
|
|
127
168
|
|
|
128
|
-
//
|
|
129
|
-
console.log('\n测试5: 测试session读取');
|
|
169
|
+
// 第二次请求使用相同的session ID(通过cookie传递)
|
|
130
170
|
const ctx2 = new MockContext();
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
171
|
+
ctx2.cookies['mm:uuid'] = session_id;
|
|
172
|
+
|
|
173
|
+
await session_mw(ctx2, mock_next);
|
|
174
|
+
|
|
175
|
+
// 验证恢复结果
|
|
176
|
+
await verifySessionRecover(ctx2, session_id);
|
|
177
|
+
} catch (err) {
|
|
178
|
+
console.log('✗ 测试失败:', err.message);
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
/**
|
|
183
|
+
* 测试session刷新功能
|
|
184
|
+
* @returns {Promise<void>} 测试结果
|
|
185
|
+
*/
|
|
186
|
+
async function testSessionRefresh() {
|
|
187
|
+
console.log('\n4. 测试session刷新功能');
|
|
188
|
+
try {
|
|
189
|
+
const session_mw = session();
|
|
190
|
+
const ctx = new MockContext();
|
|
191
|
+
|
|
192
|
+
await session_mw(ctx, async () => {
|
|
193
|
+
ctx.session.original_data = 'original';
|
|
194
|
+
ctx.session.refresh(); // 刷新session
|
|
195
|
+
});
|
|
196
|
+
|
|
197
|
+
console.log('✓ session刷新功能正常');
|
|
198
|
+
} catch (err) {
|
|
199
|
+
console.log('✗ 测试失败:', err.message);
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
/**
|
|
204
|
+
* 测试自定义配置
|
|
205
|
+
* @returns {Promise<void>} 测试结果
|
|
206
|
+
*/
|
|
207
|
+
async function testCustomConfig() {
|
|
208
|
+
console.log('\n5. 测试自定义配置');
|
|
209
|
+
try {
|
|
210
|
+
const custom_cfg = {
|
|
211
|
+
key_prefix: 'custom:session',
|
|
212
|
+
cookie_token: 'custom_token',
|
|
213
|
+
max_age: 3600 // 1小时
|
|
214
|
+
};
|
|
215
|
+
|
|
216
|
+
const session_mw = session(custom_cfg);
|
|
217
|
+
const ctx = new MockContext();
|
|
218
|
+
|
|
219
|
+
await session_mw(ctx, mock_next);
|
|
220
|
+
|
|
221
|
+
console.log('✓ 自定义配置生效');
|
|
222
|
+
console.log(' - session ID长度:', ctx.session.getId().length);
|
|
223
|
+
} catch (err) {
|
|
224
|
+
console.log('✗ 测试失败:', err.message);
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
/**
|
|
229
|
+
* 测试Session类直接使用
|
|
230
|
+
* @returns {Promise<void>} 测试结果
|
|
231
|
+
*/
|
|
232
|
+
async function testSessionClass() {
|
|
233
|
+
console.log('\n6. 测试Session类直接使用');
|
|
234
|
+
try {
|
|
235
|
+
const sess = new Session();
|
|
236
|
+
const ctx = new MockContext();
|
|
237
|
+
|
|
238
|
+
const session_obj = await sess.get(ctx);
|
|
239
|
+
console.log('✓ Session类get方法正常');
|
|
240
|
+
console.log(' - 获取的session对象:', session_obj);
|
|
241
|
+
|
|
242
|
+
// 测试保存session
|
|
243
|
+
await sess.save(ctx, session_obj);
|
|
244
|
+
console.log('✓ Session类save方法正常');
|
|
245
|
+
|
|
246
|
+
// 测试生成session ID
|
|
247
|
+
const new_sess_id = sess.genId(ctx);
|
|
248
|
+
console.log('✓ Session类genId方法正常');
|
|
249
|
+
console.log(' - 生成的session ID:', new_sess_id);
|
|
250
|
+
} catch (err) {
|
|
251
|
+
console.log('✗ 测试失败:', err.message);
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
/**
|
|
256
|
+
* 测试Store类
|
|
257
|
+
* @returns {Promise<void>} 测试结果
|
|
258
|
+
*/
|
|
259
|
+
async function testStoreClass() {
|
|
260
|
+
console.log('\n7. 测试Store类');
|
|
261
|
+
try {
|
|
262
|
+
const store = new Store('test_prefix');
|
|
263
|
+
const test_data = { key: 'value', number: 42 };
|
|
264
|
+
|
|
265
|
+
// 测试设置数据
|
|
266
|
+
await store.set('test_key', test_data, 60);
|
|
267
|
+
console.log('✓ Store类set方法正常');
|
|
268
|
+
|
|
269
|
+
// 测试获取数据
|
|
270
|
+
const ret_data = await store.get('test_key');
|
|
271
|
+
if (ret_data && ret_data.key === 'value') {
|
|
272
|
+
console.log('✓ Store类get方法正常');
|
|
273
|
+
console.log(' - 获取的数据:', ret_data);
|
|
144
274
|
} else {
|
|
145
|
-
console.log('
|
|
275
|
+
console.log('✗ Store类get方法异常');
|
|
146
276
|
}
|
|
147
277
|
|
|
148
|
-
//
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
console.log(' 生成的session ID:', sessionId);
|
|
156
|
-
|
|
157
|
-
// 测试7: 测试session销毁
|
|
158
|
-
console.log('\n测试7: 测试session销毁');
|
|
159
|
-
const ctx3 = new MockContext();
|
|
160
|
-
|
|
161
|
-
// 添加一个中间件来测试session销毁
|
|
162
|
-
const destroyApp = new MockKoaApp();
|
|
163
|
-
destroyApp.use(session.middleware());
|
|
164
|
-
destroyApp.use(async (ctx, next) => {
|
|
165
|
-
// 设置session为null触发销毁
|
|
166
|
-
ctx.session = null;
|
|
167
|
-
await next();
|
|
168
|
-
});
|
|
169
|
-
|
|
170
|
-
await destroyApp.handleRequest(ctx3);
|
|
171
|
-
console.log('✅ session销毁逻辑测试完成');
|
|
278
|
+
// 测试删除数据
|
|
279
|
+
store.del('test_key');
|
|
280
|
+
console.log('✓ Store类del方法正常');
|
|
281
|
+
} catch (err) {
|
|
282
|
+
console.log('✗ 测试失败:', err.message);
|
|
283
|
+
}
|
|
284
|
+
}
|
|
172
285
|
|
|
173
|
-
|
|
286
|
+
/**
|
|
287
|
+
* 测试session中间件
|
|
288
|
+
*/
|
|
289
|
+
async function testSession() {
|
|
290
|
+
console.log('=== 开始测试session中间件 ===\n');
|
|
174
291
|
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
292
|
+
await testBasicSession();
|
|
293
|
+
await testSessionDataRW();
|
|
294
|
+
await testSessionRecovery();
|
|
295
|
+
await testSessionRefresh();
|
|
296
|
+
await testCustomConfig();
|
|
297
|
+
await testSessionClass();
|
|
298
|
+
await testStoreClass();
|
|
299
|
+
|
|
300
|
+
console.log('\n=== session中间件测试完成 ===');
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
/**
|
|
304
|
+
* 运行测试
|
|
305
|
+
*/
|
|
306
|
+
async function runTests() {
|
|
307
|
+
try {
|
|
308
|
+
await testSession();
|
|
309
|
+
} catch (err) {
|
|
310
|
+
console.error('测试执行出错:', err);
|
|
178
311
|
}
|
|
179
312
|
}
|
|
180
313
|
|
|
181
|
-
//
|
|
314
|
+
// 如果直接运行此文件,则执行测试
|
|
182
315
|
if (require.main === module) {
|
|
183
|
-
|
|
316
|
+
runTests();
|
|
184
317
|
}
|
|
185
318
|
|
|
319
|
+
setTimeout(() => {
|
|
320
|
+
process.exit(0);
|
|
321
|
+
}, 5000);
|
|
322
|
+
|
|
186
323
|
module.exports = {
|
|
187
324
|
MockContext,
|
|
188
|
-
|
|
189
|
-
testSession
|
|
325
|
+
mock_next,
|
|
326
|
+
testSession,
|
|
327
|
+
runTests
|
|
190
328
|
};
|