mm_session 1.5.0 → 1.5.2
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 +263 -0
- package/README_EN.md +263 -0
- package/eslint.config.js +215 -0
- package/index.js +8 -92
- package/lib/session.js +259 -0
- package/lib/store.js +105 -0
- package/package.json +6 -2
- package/test.js +190 -0
- package/store.js +0 -96
package/README.md
ADDED
|
@@ -0,0 +1,263 @@
|
|
|
1
|
+
# mm_session
|
|
2
|
+
|
|
3
|
+
[English Documentation](./README_EN.md) | [中文文档](./README.md)
|
|
4
|
+
|
|
5
|
+
## 概述
|
|
6
|
+
|
|
7
|
+
`mm_session` 是一个专为 Koa.js 框架设计的轻量级 session 管理中间件。它提供了简单易用的 session 管理功能,支持自定义存储后端,适用于各种规模的 Web 应用。
|
|
8
|
+
|
|
9
|
+
## 特性
|
|
10
|
+
|
|
11
|
+
- ✅ **Koa 中间件标准** - 符合 `app.use(session.middleware())` 使用方式
|
|
12
|
+
- ✅ **存储抽象层** - 支持自定义存储后端
|
|
13
|
+
- ✅ **自动 session 管理** - 自动创建、保存、销毁 session
|
|
14
|
+
- ✅ **Cookie 自动处理** - 自动设置和读取 session cookie
|
|
15
|
+
- ✅ **安全 session ID** - 基于 IP + 时间戳 + AES 加密生成
|
|
16
|
+
- ✅ **异步支持** - 完整的 async/await 支持
|
|
17
|
+
- ✅ **轻量级** - 无冗余依赖,代码简洁
|
|
18
|
+
|
|
19
|
+
## 安装
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
npm install mm_session
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## 快速开始
|
|
26
|
+
|
|
27
|
+
### 基本用法
|
|
28
|
+
|
|
29
|
+
```javascript
|
|
30
|
+
const Koa = require('koa');
|
|
31
|
+
const { Session } = require('mm_session');
|
|
32
|
+
|
|
33
|
+
const app = new Koa();
|
|
34
|
+
|
|
35
|
+
// 创建 session 实例
|
|
36
|
+
const session = new Session({
|
|
37
|
+
key: 'my_session', // cookie 名称
|
|
38
|
+
max_age: 3600 // session 过期时间(秒)
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
// 注册中间件
|
|
42
|
+
app.use(session.middleware());
|
|
43
|
+
|
|
44
|
+
// 业务路由
|
|
45
|
+
app.use(async (ctx) => {
|
|
46
|
+
// 设置 session 数据
|
|
47
|
+
if (!ctx.session.user_id) {
|
|
48
|
+
ctx.session.user_id = 123;
|
|
49
|
+
ctx.session.username = 'test_user';
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// 读取 session 数据
|
|
53
|
+
ctx.body = {
|
|
54
|
+
user_id: ctx.session.user_id,
|
|
55
|
+
username: ctx.session.username
|
|
56
|
+
};
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
app.listen(3000);
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
### 高级配置
|
|
63
|
+
|
|
64
|
+
```javascript
|
|
65
|
+
const { Session, Store } = require('mm_session');
|
|
66
|
+
|
|
67
|
+
// 自定义配置
|
|
68
|
+
const session = new Session({
|
|
69
|
+
key: 'app_session', // cookie 键名
|
|
70
|
+
max_age: 7200, // 过期时间:2小时
|
|
71
|
+
http_only: true, // 仅 HTTP 访问
|
|
72
|
+
secure: process.env.NODE_ENV === 'production', // 生产环境 HTTPS
|
|
73
|
+
same_site: 'strict' // 同站策略
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
// 自定义存储(可选)
|
|
77
|
+
const customStore = new Store('custom_prefix');
|
|
78
|
+
session.init(customStore);
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
## API 文档
|
|
82
|
+
|
|
83
|
+
### Session 类
|
|
84
|
+
|
|
85
|
+
#### 构造函数
|
|
86
|
+
|
|
87
|
+
```javascript
|
|
88
|
+
new Session(config)
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
**参数:**
|
|
92
|
+
- `config` (Object) - 配置对象
|
|
93
|
+
- `key` (String) - session cookie 名称,默认: 'mm:uuid'
|
|
94
|
+
- `max_age` (Number) - session 过期时间(秒)
|
|
95
|
+
- 其他 cookie 配置选项
|
|
96
|
+
|
|
97
|
+
#### 方法
|
|
98
|
+
|
|
99
|
+
##### middleware()
|
|
100
|
+
返回 Koa 中间件函数。
|
|
101
|
+
|
|
102
|
+
```javascript
|
|
103
|
+
app.use(session.middleware());
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
##### init(store)
|
|
107
|
+
初始化自定义存储后端。
|
|
108
|
+
|
|
109
|
+
```javascript
|
|
110
|
+
session.init(new CustomStore());
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
### Store 类
|
|
114
|
+
|
|
115
|
+
存储抽象类,支持自定义存储实现。
|
|
116
|
+
|
|
117
|
+
```javascript
|
|
118
|
+
const { Store } = require('mm_session');
|
|
119
|
+
const store = new Store('prefix_');
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
## 配置选项
|
|
123
|
+
|
|
124
|
+
### Session 配置
|
|
125
|
+
|
|
126
|
+
| 选项 | 类型 | 默认值 | 描述 |
|
|
127
|
+
|------|------|--------|------|
|
|
128
|
+
| key | String | 'mm:uuid' | session cookie 名称 |
|
|
129
|
+
| max_age | Number | - | session 过期时间(秒) |
|
|
130
|
+
| http_only | Boolean | true | 仅 HTTP 访问 |
|
|
131
|
+
| secure | Boolean | false | 仅 HTTPS 传输 |
|
|
132
|
+
| same_site | String | 'lax' | 同站策略 |
|
|
133
|
+
|
|
134
|
+
### Cookie 配置
|
|
135
|
+
|
|
136
|
+
支持所有 [cookie](https://github.com/jshttp/cookie) 库的配置选项。
|
|
137
|
+
|
|
138
|
+
## 存储后端
|
|
139
|
+
|
|
140
|
+
### 默认存储
|
|
141
|
+
默认使用 `mm_cachebase` 作为存储后端,支持内存和文件持久化。
|
|
142
|
+
|
|
143
|
+
### 自定义存储
|
|
144
|
+
可以实现自定义存储类,只需实现以下接口:
|
|
145
|
+
|
|
146
|
+
```javascript
|
|
147
|
+
class CustomStore {
|
|
148
|
+
async get(sessionId) {}
|
|
149
|
+
async set(sessionData, options, ctx) {}
|
|
150
|
+
async destroy(sessionId, ctx) {}
|
|
151
|
+
async getID(ctx) {}
|
|
152
|
+
}
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
## 示例应用
|
|
156
|
+
|
|
157
|
+
### 用户登录系统
|
|
158
|
+
|
|
159
|
+
```javascript
|
|
160
|
+
const session = new Session({
|
|
161
|
+
key: 'user_session',
|
|
162
|
+
max_age: 86400 // 24小时
|
|
163
|
+
});
|
|
164
|
+
|
|
165
|
+
app.use(session.middleware());
|
|
166
|
+
|
|
167
|
+
// 登录路由
|
|
168
|
+
app.use(async (ctx, next) => {
|
|
169
|
+
if (ctx.path === '/login' && ctx.method === 'POST') {
|
|
170
|
+
const { username, password } = ctx.request.body;
|
|
171
|
+
|
|
172
|
+
// 验证用户(示例)
|
|
173
|
+
if (username === 'admin' && password === 'password') {
|
|
174
|
+
ctx.session.user = {
|
|
175
|
+
id: 1,
|
|
176
|
+
username: 'admin',
|
|
177
|
+
role: 'administrator'
|
|
178
|
+
};
|
|
179
|
+
ctx.body = { success: true };
|
|
180
|
+
} else {
|
|
181
|
+
ctx.body = { success: false, error: '认证失败' };
|
|
182
|
+
}
|
|
183
|
+
} else {
|
|
184
|
+
await next();
|
|
185
|
+
}
|
|
186
|
+
});
|
|
187
|
+
|
|
188
|
+
// 需要认证的路由
|
|
189
|
+
app.use(async (ctx, next) => {
|
|
190
|
+
if (!ctx.session.user) {
|
|
191
|
+
ctx.status = 401;
|
|
192
|
+
ctx.body = { error: '请先登录' };
|
|
193
|
+
return;
|
|
194
|
+
}
|
|
195
|
+
await next();
|
|
196
|
+
});
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
## 测试
|
|
200
|
+
|
|
201
|
+
```bash
|
|
202
|
+
# 运行测试
|
|
203
|
+
npm test
|
|
204
|
+
|
|
205
|
+
# 或直接运行
|
|
206
|
+
node test.js
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
## 开发
|
|
210
|
+
|
|
211
|
+
### 代码规范
|
|
212
|
+
|
|
213
|
+
项目使用 ESLint 进行代码规范检查:
|
|
214
|
+
|
|
215
|
+
```bash
|
|
216
|
+
# 检查代码规范
|
|
217
|
+
npx eslint lib/session.js
|
|
218
|
+
|
|
219
|
+
# 自动修复
|
|
220
|
+
npx eslint lib/session.js --fix
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
### 项目结构
|
|
224
|
+
|
|
225
|
+
```
|
|
226
|
+
mm_session/
|
|
227
|
+
├── lib/
|
|
228
|
+
│ ├── session.js # Session 类实现
|
|
229
|
+
│ └── store.js # Store 类实现
|
|
230
|
+
├── index.js # 模块入口
|
|
231
|
+
├── test.js # 测试文件
|
|
232
|
+
├── eslint.config.js # ESLint 配置
|
|
233
|
+
└── package.json # 项目配置
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
## 贡献
|
|
237
|
+
|
|
238
|
+
欢迎提交 Issue 和 Pull Request!
|
|
239
|
+
|
|
240
|
+
## 许可证
|
|
241
|
+
|
|
242
|
+
ISC License
|
|
243
|
+
|
|
244
|
+
## 作者
|
|
245
|
+
|
|
246
|
+
邱文武
|
|
247
|
+
|
|
248
|
+
## 更新日志
|
|
249
|
+
|
|
250
|
+
### v1.5.1
|
|
251
|
+
- 修复 session 保存逻辑
|
|
252
|
+
- 优化 cookie 设置机制
|
|
253
|
+
- 改进测试用例
|
|
254
|
+
|
|
255
|
+
### v1.5.0
|
|
256
|
+
- 重构为类+原型函数模式
|
|
257
|
+
- 符合 Koa 中间件标准使用方式
|
|
258
|
+
- 增强代码可维护性
|
|
259
|
+
|
|
260
|
+
## 相关项目
|
|
261
|
+
|
|
262
|
+
- [mm_cachebase](https://www.npmjs.com/package/mm_cachebase) - 缓存基础库
|
|
263
|
+
- [mm_eslint](https://www.npmjs.com/package/mm_eslint) - ESLint 配置
|
package/README_EN.md
ADDED
|
@@ -0,0 +1,263 @@
|
|
|
1
|
+
# mm_session
|
|
2
|
+
|
|
3
|
+
[English Documentation](README_EN.md) | [中文文档](README.md)
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
`mm_session` is a lightweight session management middleware designed specifically for the Koa.js framework. It provides simple and easy-to-use session management functionality with support for custom storage backends, suitable for web applications of all sizes.
|
|
8
|
+
|
|
9
|
+
## Features
|
|
10
|
+
|
|
11
|
+
- ✅ **Koa Middleware Standard** - Compatible with `app.use(session.middleware())` usage
|
|
12
|
+
- ✅ **Storage Abstraction Layer** - Supports custom storage backends
|
|
13
|
+
- ✅ **Automatic Session Management** - Automatic session creation, saving, and destruction
|
|
14
|
+
- ✅ **Cookie Auto-handling** - Automatic session cookie setting and reading
|
|
15
|
+
- ✅ **Secure Session ID** - Generated based on IP + timestamp + AES encryption
|
|
16
|
+
- ✅ **Async Support** - Full async/await support
|
|
17
|
+
- ✅ **Lightweight** - No redundant dependencies, clean codebase
|
|
18
|
+
|
|
19
|
+
## Installation
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
npm install mm_session
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Quick Start
|
|
26
|
+
|
|
27
|
+
### Basic Usage
|
|
28
|
+
|
|
29
|
+
```javascript
|
|
30
|
+
const Koa = require('koa');
|
|
31
|
+
const { Session } = require('mm_session');
|
|
32
|
+
|
|
33
|
+
const app = new Koa();
|
|
34
|
+
|
|
35
|
+
// Create session instance
|
|
36
|
+
const session = new Session({
|
|
37
|
+
key: 'my_session', // cookie name
|
|
38
|
+
max_age: 3600 // session expiration time (seconds)
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
// Register middleware
|
|
42
|
+
app.use(session.middleware());
|
|
43
|
+
|
|
44
|
+
// Business routes
|
|
45
|
+
app.use(async (ctx) => {
|
|
46
|
+
// Set session data
|
|
47
|
+
if (!ctx.session.user_id) {
|
|
48
|
+
ctx.session.user_id = 123;
|
|
49
|
+
ctx.session.username = 'test_user';
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// Read session data
|
|
53
|
+
ctx.body = {
|
|
54
|
+
user_id: ctx.session.user_id,
|
|
55
|
+
username: ctx.session.username
|
|
56
|
+
};
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
app.listen(3000);
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
### Advanced Configuration
|
|
63
|
+
|
|
64
|
+
```javascript
|
|
65
|
+
const { Session, Store } = require('mm_session');
|
|
66
|
+
|
|
67
|
+
// Custom configuration
|
|
68
|
+
const session = new Session({
|
|
69
|
+
key: 'app_session', // cookie key name
|
|
70
|
+
max_age: 7200, // expiration time: 2 hours
|
|
71
|
+
http_only: true, // HTTP-only access
|
|
72
|
+
secure: process.env.NODE_ENV === 'production', // HTTPS in production
|
|
73
|
+
same_site: 'strict' // same-site policy
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
// Custom storage (optional)
|
|
77
|
+
const customStore = new Store('custom_prefix');
|
|
78
|
+
session.init(customStore);
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
## API Documentation
|
|
82
|
+
|
|
83
|
+
### Session Class
|
|
84
|
+
|
|
85
|
+
#### Constructor
|
|
86
|
+
|
|
87
|
+
```javascript
|
|
88
|
+
new Session(config)
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
**Parameters:**
|
|
92
|
+
- `config` (Object) - Configuration object
|
|
93
|
+
- `key` (String) - Session cookie name, default: 'mm:uuid'
|
|
94
|
+
- `max_age` (Number) - Session expiration time (seconds)
|
|
95
|
+
- Other cookie configuration options
|
|
96
|
+
|
|
97
|
+
#### Methods
|
|
98
|
+
|
|
99
|
+
##### middleware()
|
|
100
|
+
Returns Koa middleware function.
|
|
101
|
+
|
|
102
|
+
```javascript
|
|
103
|
+
app.use(session.middleware());
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
##### init(store)
|
|
107
|
+
Initialize custom storage backend.
|
|
108
|
+
|
|
109
|
+
```javascript
|
|
110
|
+
session.init(new CustomStore());
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
### Store Class
|
|
114
|
+
|
|
115
|
+
Storage abstraction class supporting custom storage implementations.
|
|
116
|
+
|
|
117
|
+
```javascript
|
|
118
|
+
const { Store } = require('mm_session');
|
|
119
|
+
const store = new Store('prefix_');
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
## Configuration Options
|
|
123
|
+
|
|
124
|
+
### Session Configuration
|
|
125
|
+
|
|
126
|
+
| Option | Type | Default | Description |
|
|
127
|
+
|--------|------|---------|-------------|
|
|
128
|
+
| key | String | 'mm:uuid' | Session cookie name |
|
|
129
|
+
| max_age | Number | - | Session expiration time (seconds) |
|
|
130
|
+
| http_only | Boolean | true | HTTP-only access |
|
|
131
|
+
| secure | Boolean | false | HTTPS-only transmission |
|
|
132
|
+
| same_site | String | 'lax' | Same-site policy |
|
|
133
|
+
|
|
134
|
+
### Cookie Configuration
|
|
135
|
+
|
|
136
|
+
Supports all [cookie](https://github.com/jshttp/cookie) library configuration options.
|
|
137
|
+
|
|
138
|
+
## Storage Backends
|
|
139
|
+
|
|
140
|
+
### Default Storage
|
|
141
|
+
Uses `mm_cachebase` as the default storage backend, supporting both memory and file persistence.
|
|
142
|
+
|
|
143
|
+
### Custom Storage
|
|
144
|
+
You can implement custom storage classes by implementing the following interface:
|
|
145
|
+
|
|
146
|
+
```javascript
|
|
147
|
+
class CustomStore {
|
|
148
|
+
async get(sessionId) {}
|
|
149
|
+
async set(sessionData, options, ctx) {}
|
|
150
|
+
async destroy(sessionId, ctx) {}
|
|
151
|
+
async getID(ctx) {}
|
|
152
|
+
}
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
## Example Applications
|
|
156
|
+
|
|
157
|
+
### User Login System
|
|
158
|
+
|
|
159
|
+
```javascript
|
|
160
|
+
const session = new Session({
|
|
161
|
+
key: 'user_session',
|
|
162
|
+
max_age: 86400 // 24 hours
|
|
163
|
+
});
|
|
164
|
+
|
|
165
|
+
app.use(session.middleware());
|
|
166
|
+
|
|
167
|
+
// Login route
|
|
168
|
+
app.use(async (ctx, next) => {
|
|
169
|
+
if (ctx.path === '/login' && ctx.method === 'POST') {
|
|
170
|
+
const { username, password } = ctx.request.body;
|
|
171
|
+
|
|
172
|
+
// User authentication (example)
|
|
173
|
+
if (username === 'admin' && password === 'password') {
|
|
174
|
+
ctx.session.user = {
|
|
175
|
+
id: 1,
|
|
176
|
+
username: 'admin',
|
|
177
|
+
role: 'administrator'
|
|
178
|
+
};
|
|
179
|
+
ctx.body = { success: true };
|
|
180
|
+
} else {
|
|
181
|
+
ctx.body = { success: false, error: 'Authentication failed' };
|
|
182
|
+
}
|
|
183
|
+
} else {
|
|
184
|
+
await next();
|
|
185
|
+
}
|
|
186
|
+
});
|
|
187
|
+
|
|
188
|
+
// Routes requiring authentication
|
|
189
|
+
app.use(async (ctx, next) => {
|
|
190
|
+
if (!ctx.session.user) {
|
|
191
|
+
ctx.status = 401;
|
|
192
|
+
ctx.body = { error: 'Please login first' };
|
|
193
|
+
return;
|
|
194
|
+
}
|
|
195
|
+
await next();
|
|
196
|
+
});
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
## Testing
|
|
200
|
+
|
|
201
|
+
```bash
|
|
202
|
+
# Run tests
|
|
203
|
+
npm test
|
|
204
|
+
|
|
205
|
+
# Or run directly
|
|
206
|
+
node test.js
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
## Development
|
|
210
|
+
|
|
211
|
+
### Code Style
|
|
212
|
+
|
|
213
|
+
The project uses ESLint for code style checking:
|
|
214
|
+
|
|
215
|
+
```bash
|
|
216
|
+
# Check code style
|
|
217
|
+
npx eslint lib/session.js
|
|
218
|
+
|
|
219
|
+
# Auto-fix issues
|
|
220
|
+
npx eslint lib/session.js --fix
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
### Project Structure
|
|
224
|
+
|
|
225
|
+
```
|
|
226
|
+
mm_session/
|
|
227
|
+
├── lib/
|
|
228
|
+
│ ├── session.js # Session class implementation
|
|
229
|
+
│ └── store.js # Store class implementation
|
|
230
|
+
├── index.js # Module entry point
|
|
231
|
+
├── test.js # Test file
|
|
232
|
+
├── eslint.config.js # ESLint configuration
|
|
233
|
+
└── package.json # Project configuration
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
## Contributing
|
|
237
|
+
|
|
238
|
+
Issues and Pull Requests are welcome!
|
|
239
|
+
|
|
240
|
+
## License
|
|
241
|
+
|
|
242
|
+
ISC License
|
|
243
|
+
|
|
244
|
+
## Author
|
|
245
|
+
|
|
246
|
+
Qiu Wenwu
|
|
247
|
+
|
|
248
|
+
## Changelog
|
|
249
|
+
|
|
250
|
+
### v1.5.1
|
|
251
|
+
- Fixed session saving logic
|
|
252
|
+
- Optimized cookie setting mechanism
|
|
253
|
+
- Improved test cases
|
|
254
|
+
|
|
255
|
+
### v1.5.0
|
|
256
|
+
- Refactored to class + prototype function pattern
|
|
257
|
+
- Compatible with Koa middleware standard usage
|
|
258
|
+
- Enhanced code maintainability
|
|
259
|
+
|
|
260
|
+
## Related Projects
|
|
261
|
+
|
|
262
|
+
- [mm_cachebase](https://www.npmjs.com/package/mm_cachebase) - Cache base library
|
|
263
|
+
- [mm_eslint](https://www.npmjs.com/package/mm_eslint) - ESLint configuration
|