mm_os 3.2.9 → 3.3.1
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 +47 -1
- package/core/base/mqtt/index.js +1109 -1106
- package/core/base/web/index.js +245 -156
- package/core/com/event/README.md +4 -4
- package/core/com/event/com.json +3 -3
- package/core/com/event/config.tpl.json +18 -18
- package/core/com/event/drive.js +132 -132
- package/core/com/event/index.js +344 -344
- package/core/com/event/script.js +25 -25
- package/core/com/middleware/com.js +152 -151
- package/core/com/socket/config.tpl.json +2 -2
- package/core/com/socket/drive.js +2 -2
- package/core/com/socket/index.js +1 -1
- package/core/com/sql/drive.js +7 -7
- package/core/com/static/index.js +1 -1
- package/index.js +34 -5
- package/middleware/cors/index.js +112 -96
- package/middleware/cors/middleware.json +18 -7
- package/middleware/csrf/index.js +202 -0
- package/middleware/csrf/middleware.json +24 -0
- package/middleware/ip_firewall/index.js +476 -0
- package/middleware/ip_firewall/middleware.json +109 -0
- package/middleware/mqtt_base/middleware.json +2 -1
- package/middleware/security_audit/index.js +543 -0
- package/middleware/security_audit/middleware.json +48 -0
- package/middleware/waf/index.js +273 -7
- package/middleware/waf/middleware.json +2 -1
- package/middleware/waf_ddos/index.js +520 -0
- package/middleware/waf_ddos/middleware.json +38 -0
- package/middleware/waf_xss/index.js +269 -0
- package/middleware/waf_xss/middleware.json +18 -0
- package/middleware/web_after/middleware.json +2 -1
- package/middleware/web_base/middleware.json +2 -1
- package/middleware/web_before/middleware.json +3 -2
- package/middleware/web_check/middleware.json +2 -1
- package/middleware/web_main/middleware.json +2 -1
- package/middleware/web_proxy/middleware.json +2 -1
- package/middleware/web_render/middleware.json +2 -1
- package/middleware/web_socket/middleware.json +4 -3
- package/middleware/web_static/middleware.json +2 -1
- package/package.json +28 -15
- package/middleware/log/index.js +0 -32
- package/middleware/log/middleware.json +0 -9
- package/middleware/performance/index.js +0 -143
- package/middleware/performance/middleware.json +0 -16
- package/middleware/rate_limit/index.js +0 -112
- package/middleware/rate_limit/middleware.json +0 -10
- package/middleware/waf_ip/index.js +0 -168
- package/middleware/waf_ip/middleware.json +0 -10
- package/nodemon.json +0 -31
- package/package.txt +0 -1
- package/rps.bat +0 -3
- package/test.js +0 -10
- package/tps.bat +0 -3
- package/update.bat +0 -1
- package//347/263/273/347/273/237/346/236/266/346/236/204/350/257/204/344/274/260/344/270/216/344/274/230/345/214/226/345/273/272/350/256/256.md +0 -599
package/middleware/cors/index.js
CHANGED
|
@@ -1,103 +1,119 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
* @param {Object} config 配置参数
|
|
2
|
+
* CORS跨域中间件
|
|
3
|
+
* 处理跨域资源共享(CORS)配置
|
|
5
4
|
*/
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
5
|
+
class CorsMiddleware {
|
|
6
|
+
constructor() {
|
|
7
|
+
this.default = {
|
|
8
|
+
// 启用CORS
|
|
9
|
+
enable: true,
|
|
10
|
+
// 允许的源
|
|
11
|
+
origin: '*',
|
|
12
|
+
// 允许的请求头
|
|
13
|
+
headers: '*',
|
|
14
|
+
// 允许的HTTP方法
|
|
15
|
+
methods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS', 'HEAD'],
|
|
16
|
+
// 允许携带凭证
|
|
17
|
+
credentials: false,
|
|
18
|
+
// 预检请求的有效期(秒)
|
|
19
|
+
max_age: 3600,
|
|
20
|
+
// 暴露的响应头
|
|
21
|
+
expose_headers: [],
|
|
22
|
+
// 忽略的路径
|
|
23
|
+
ignore_paths: []
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
}
|
|
14
27
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
28
|
+
CorsMiddleware.prototype.init = function(config) {
|
|
29
|
+
this.config = Object.assign({}, this.default, config || {});
|
|
30
|
+
return this;
|
|
31
|
+
};
|
|
19
32
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
33
|
+
CorsMiddleware.prototype.run = async function(ctx, next) {
|
|
34
|
+
const config = this.config;
|
|
35
|
+
|
|
36
|
+
if (!config.enable) {
|
|
37
|
+
return await next();
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// 检查是否应该忽略该路径
|
|
41
|
+
const path = ctx.path;
|
|
42
|
+
if (config.ignore_paths.some(p => path.startsWith(p))) {
|
|
43
|
+
return await next();
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// 设置CORS头
|
|
47
|
+
this._setCorsHeaders(ctx, config);
|
|
48
|
+
|
|
49
|
+
// 处理预检请求
|
|
50
|
+
if (ctx.method === 'OPTIONS') {
|
|
51
|
+
ctx.status = 204;
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
await next();
|
|
56
|
+
};
|
|
23
57
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
58
|
+
CorsMiddleware.prototype._setCorsHeaders = function(ctx, config) {
|
|
59
|
+
// 设置Access-Control-Allow-Origin
|
|
60
|
+
if (config.origin === '*') {
|
|
61
|
+
ctx.set('Access-Control-Allow-Origin', '*');
|
|
62
|
+
} else if (Array.isArray(config.origin)) {
|
|
63
|
+
const requestOrigin = ctx.get('Origin');
|
|
64
|
+
if (config.origin.includes(requestOrigin)) {
|
|
65
|
+
ctx.set('Access-Control-Allow-Origin', requestOrigin);
|
|
66
|
+
}
|
|
67
|
+
} else {
|
|
68
|
+
ctx.set('Access-Control-Allow-Origin', config.origin);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// 设置Access-Control-Allow-Headers
|
|
72
|
+
if (config.headers === '*') {
|
|
73
|
+
ctx.set('Access-Control-Allow-Headers', '*');
|
|
74
|
+
} else if (Array.isArray(config.headers)) {
|
|
75
|
+
ctx.set('Access-Control-Allow-Headers', config.headers.join(', '));
|
|
76
|
+
} else {
|
|
77
|
+
ctx.set('Access-Control-Allow-Headers', config.headers);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// 设置Access-Control-Allow-Methods
|
|
81
|
+
ctx.set('Access-Control-Allow-Methods', config.methods.join(', '));
|
|
82
|
+
|
|
83
|
+
// 设置Access-Control-Allow-Credentials
|
|
84
|
+
if (config.credentials) {
|
|
85
|
+
ctx.set('Access-Control-Allow-Credentials', 'true');
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// 设置Access-Control-Max-Age
|
|
89
|
+
if (config.max_age > 0) {
|
|
90
|
+
ctx.set('Access-Control-Max-Age', config.max_age.toString());
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// 设置Access-Control-Expose-Headers
|
|
94
|
+
if (config.expose_headers.length > 0) {
|
|
95
|
+
ctx.set('Access-Control-Expose-Headers', config.expose_headers.join(', '));
|
|
96
|
+
}
|
|
97
|
+
};
|
|
29
98
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
// ctx.set("Access-Control-Allow-Credentials", 'false');
|
|
99
|
+
// 创建中间件实例
|
|
100
|
+
const middleware = new CorsMiddleware();
|
|
33
101
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
await next();
|
|
53
|
-
}
|
|
54
|
-
} catch (error) {
|
|
55
|
-
$.log.error('CORS中间件错误(origin限制):', error);
|
|
56
|
-
// 出错时默认允许请求继续处理
|
|
57
|
-
await next();
|
|
58
|
-
}
|
|
59
|
-
});
|
|
60
|
-
} else if (cos.headers && cos.headers !== "*") {
|
|
61
|
-
/* 跨域限制(web防火墙) */
|
|
62
|
-
server.use(async (ctx, next) => {
|
|
63
|
-
try {
|
|
64
|
-
var req = ctx.request;
|
|
65
|
-
// 允许来自所有域名请求
|
|
66
|
-
ctx.set('Access-Control-Allow-Origin', '*');
|
|
67
|
-
// ctx.set('Access-Control-Allow-Methods', 'GET,POST,OPTIONS');
|
|
68
|
-
if (req.method === 'OPTIONS') {
|
|
69
|
-
ctx.set('Access-Control-Allow-Headers', cos.headers);
|
|
70
|
-
ctx.status = 204;
|
|
71
|
-
} else {
|
|
72
|
-
await next();
|
|
73
|
-
}
|
|
74
|
-
} catch (error) {
|
|
75
|
-
$.log.error('CORS中间件错误(headers限制):', error);
|
|
76
|
-
// 出错时默认允许请求继续处理
|
|
77
|
-
await next();
|
|
78
|
-
}
|
|
79
|
-
});
|
|
80
|
-
} else {
|
|
81
|
-
/* 跨域限制(web防火墙) */
|
|
82
|
-
server.use(async (ctx, next) => {
|
|
83
|
-
try {
|
|
84
|
-
var req = ctx.request;
|
|
85
|
-
// 允许来自所有域名请求
|
|
86
|
-
ctx.set('Access-Control-Allow-Origin', '*');
|
|
87
|
-
// ctx.set('Access-Control-Allow-Methods', 'GET,POST,OPTIONS');
|
|
88
|
-
if (req.method === 'OPTIONS') {
|
|
89
|
-
ctx.set('Access-Control-Allow-Headers', '*');
|
|
90
|
-
ctx.status = 204;
|
|
91
|
-
} else {
|
|
92
|
-
await next();
|
|
93
|
-
}
|
|
94
|
-
} catch (error) {
|
|
95
|
-
$.log.error('CORS中间件错误(完全宽松):', error);
|
|
96
|
-
// 出错时默认允许请求继续处理
|
|
97
|
-
await next();
|
|
98
|
-
}
|
|
99
|
-
});
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
return server;
|
|
103
|
-
};
|
|
102
|
+
// 导出符合系统期望的函数
|
|
103
|
+
exports = module.exports = function(server, config) {
|
|
104
|
+
// 初始化中间件
|
|
105
|
+
middleware.init(config);
|
|
106
|
+
|
|
107
|
+
// 注册中间件到服务器
|
|
108
|
+
server.use(middleware.run.bind(middleware));
|
|
109
|
+
|
|
110
|
+
// 记录中间件初始化信息
|
|
111
|
+
if ($.log && $.log.info) {
|
|
112
|
+
$.log.info(`CORS中间件已加载: 启用=${middleware.config.enable}, 源=${middleware.config.origin}`);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
return server;
|
|
116
|
+
};
|
|
117
|
+
|
|
118
|
+
// 保留原始实例,以便其他方式调用
|
|
119
|
+
exports.middleware = middleware;
|
|
@@ -1,9 +1,20 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
2
|
+
"name": "cors",
|
|
3
|
+
"title": "CORS跨域中间件",
|
|
4
|
+
"description": "处理跨域资源共享(CORS)配置,支持灵活的跨域策略",
|
|
5
|
+
"version": "1.0",
|
|
6
|
+
"type": "web",
|
|
7
|
+
"process_type": "common_before",
|
|
8
|
+
"sort": 15,
|
|
9
|
+
"state": 1,
|
|
10
|
+
"config": {
|
|
11
|
+
"enable": true,
|
|
12
|
+
"origin": "*",
|
|
13
|
+
"headers": "*",
|
|
14
|
+
"methods": ["GET", "POST", "PUT", "DELETE", "OPTIONS", "HEAD"],
|
|
15
|
+
"credentials": false,
|
|
16
|
+
"max_age": 3600,
|
|
17
|
+
"expose_headers": [],
|
|
18
|
+
"ignore_paths": []
|
|
19
|
+
}
|
|
9
20
|
}
|
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CSRF保护中间件
|
|
3
|
+
* 防止跨站请求伪造攻击
|
|
4
|
+
*/
|
|
5
|
+
class CsrfMiddleware {
|
|
6
|
+
constructor() {
|
|
7
|
+
this.default = {
|
|
8
|
+
// 启用CSRF保护
|
|
9
|
+
enable: true,
|
|
10
|
+
// CSRF令牌的Cookie名称
|
|
11
|
+
cookie_name: 'csrf_token',
|
|
12
|
+
// CSRF令牌的请求头名称
|
|
13
|
+
header_name: 'X-CSRF-Token',
|
|
14
|
+
// CSRF令牌的表单字段名称
|
|
15
|
+
form_field: '_csrf',
|
|
16
|
+
// CSRF令牌的过期时间(毫秒)
|
|
17
|
+
max_age: 3600000, // 1小时
|
|
18
|
+
// 忽略的HTTP方法
|
|
19
|
+
ignore_methods: ['GET', 'HEAD', 'OPTIONS'],
|
|
20
|
+
// 忽略的路径
|
|
21
|
+
ignore_paths: [],
|
|
22
|
+
// 是否生成新的令牌
|
|
23
|
+
generate_new: true,
|
|
24
|
+
// 是否验证来源
|
|
25
|
+
check_origin: true,
|
|
26
|
+
// 是否记录CSRF攻击尝试
|
|
27
|
+
log: true,
|
|
28
|
+
// 是否阻止恶意请求
|
|
29
|
+
block: true,
|
|
30
|
+
// 允许的来源域名
|
|
31
|
+
allowed_origins: []
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
CsrfMiddleware.prototype.init = function(config) {
|
|
37
|
+
this.config = Object.assign({}, this.default, config || {});
|
|
38
|
+
return this;
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
CsrfMiddleware.prototype.run = async function(ctx, next) {
|
|
42
|
+
const config = this.config;
|
|
43
|
+
|
|
44
|
+
if (!config.enable) {
|
|
45
|
+
return await next();
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// 生成CSRF令牌
|
|
49
|
+
const token = await this._generateToken(ctx);
|
|
50
|
+
|
|
51
|
+
// 将令牌添加到上下文,供模板使用
|
|
52
|
+
ctx.state.csrf = token;
|
|
53
|
+
|
|
54
|
+
// 检查是否需要验证CSRF
|
|
55
|
+
if (!this._shouldSkipCsrfValidation(ctx, config)) {
|
|
56
|
+
// 验证来源
|
|
57
|
+
if (config.check_origin && !this._validateOrigin(ctx, config)) {
|
|
58
|
+
if (config.block) {
|
|
59
|
+
ctx.status = 403;
|
|
60
|
+
ctx.body = {
|
|
61
|
+
code: 403,
|
|
62
|
+
msg: 'Forbidden: Invalid request origin'
|
|
63
|
+
};
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// 验证CSRF令牌
|
|
69
|
+
if (!this._validateToken(ctx, config)) {
|
|
70
|
+
if (config.block) {
|
|
71
|
+
ctx.status = 403;
|
|
72
|
+
ctx.body = {
|
|
73
|
+
code: 403,
|
|
74
|
+
msg: 'Forbidden: Invalid CSRF token'
|
|
75
|
+
};
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// 如果需要生成新令牌
|
|
81
|
+
if (config.generate_new) {
|
|
82
|
+
await this._setNewToken(ctx, config);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
await next();
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
CsrfMiddleware.prototype._generateToken = async function(ctx) {
|
|
90
|
+
let token = ctx.cookies.get(this.config.cookie_name);
|
|
91
|
+
|
|
92
|
+
// 如果没有令牌或需要生成新令牌,则创建一个新的
|
|
93
|
+
if (!token || this.config.generate_new) {
|
|
94
|
+
await this._setNewToken(ctx, this.config);
|
|
95
|
+
token = ctx.cookies.get(this.config.cookie_name);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
return token;
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
CsrfMiddleware.prototype._setNewToken = async function(ctx, config) {
|
|
102
|
+
// 生成随机令牌
|
|
103
|
+
const token = this._createRandomToken();
|
|
104
|
+
|
|
105
|
+
// 将令牌存储到Cookie
|
|
106
|
+
ctx.cookies.set(config.cookie_name, token, {
|
|
107
|
+
httpOnly: false, // CSRF令牌需要从前端读取,所以不能设置httpOnly
|
|
108
|
+
maxAge: config.max_age,
|
|
109
|
+
sameSite: 'lax'
|
|
110
|
+
});
|
|
111
|
+
};
|
|
112
|
+
|
|
113
|
+
CsrfMiddleware.prototype._createRandomToken = function() {
|
|
114
|
+
return Math.random().toString(36).substring(2) +
|
|
115
|
+
Math.random().toString(36).substring(2) +
|
|
116
|
+
Math.random().toString(36).substring(2);
|
|
117
|
+
};
|
|
118
|
+
|
|
119
|
+
CsrfMiddleware.prototype._shouldSkipCsrfValidation = function(ctx, config) {
|
|
120
|
+
const method = ctx.method;
|
|
121
|
+
const path = ctx.path;
|
|
122
|
+
|
|
123
|
+
// 检查是否在忽略的方法列表中
|
|
124
|
+
if (config.ignore_methods.includes(method)) {
|
|
125
|
+
return true;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
// 检查是否在忽略的路径列表中
|
|
129
|
+
if (config.ignore_paths.some(p => path.startsWith(p))) {
|
|
130
|
+
return true;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
return false;
|
|
134
|
+
};
|
|
135
|
+
|
|
136
|
+
CsrfMiddleware.prototype._validateOrigin = function(ctx, config) {
|
|
137
|
+
const origin = ctx.get('Origin');
|
|
138
|
+
const host = ctx.get('Host');
|
|
139
|
+
|
|
140
|
+
// 如果没有Origin头,可能是同源请求
|
|
141
|
+
if (!origin) {
|
|
142
|
+
return true;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
// 检查是否在允许的来源列表中
|
|
146
|
+
if (config.allowed_origins.length > 0) {
|
|
147
|
+
return config.allowed_origins.includes(origin);
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
// 默认情况下,只允许同源请求
|
|
151
|
+
return origin.includes(host);
|
|
152
|
+
};
|
|
153
|
+
|
|
154
|
+
CsrfMiddleware.prototype._validateToken = function(ctx, config) {
|
|
155
|
+
const tokenFromCookie = ctx.cookies.get(config.cookie_name);
|
|
156
|
+
|
|
157
|
+
// 从请求头获取令牌
|
|
158
|
+
const tokenFromHeader = ctx.get(config.header_name);
|
|
159
|
+
|
|
160
|
+
// 从请求体获取令牌
|
|
161
|
+
let tokenFromBody = null;
|
|
162
|
+
if (ctx.request.body && ctx.request.body[config.form_field]) {
|
|
163
|
+
tokenFromBody = ctx.request.body[config.form_field];
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
// 从查询参数获取令牌
|
|
167
|
+
const tokenFromQuery = ctx.query[config.form_field];
|
|
168
|
+
|
|
169
|
+
// 检查令牌是否匹配
|
|
170
|
+
const receivedToken = tokenFromHeader || tokenFromBody || tokenFromQuery;
|
|
171
|
+
|
|
172
|
+
if (!receivedToken || !tokenFromCookie) {
|
|
173
|
+
return false;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
return receivedToken === tokenFromCookie;
|
|
177
|
+
};
|
|
178
|
+
|
|
179
|
+
// 创建中间件实例
|
|
180
|
+
const middleware = new CsrfMiddleware();
|
|
181
|
+
|
|
182
|
+
// 导出符合系统期望的函数
|
|
183
|
+
exports = module.exports = function(server, config) {
|
|
184
|
+
// 获取当前中间件的配置(从middleware.json加载的配置)
|
|
185
|
+
var middleware_config = this && this.config ? this.config : config;
|
|
186
|
+
|
|
187
|
+
// 初始化中间件
|
|
188
|
+
middleware.init(middleware_config);
|
|
189
|
+
|
|
190
|
+
// 注册中间件到服务器
|
|
191
|
+
server.use(middleware.run.bind(middleware));
|
|
192
|
+
|
|
193
|
+
// 记录中间件初始化信息
|
|
194
|
+
if ($.log && $.log.info) {
|
|
195
|
+
$.log.info(`CSRF中间件已加载: 启用=${middleware.config.enable}, 忽略路径=${middleware.config.ignore_paths.length}`);
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
return server;
|
|
199
|
+
};
|
|
200
|
+
|
|
201
|
+
// 保留原始实例,以便其他方式调用
|
|
202
|
+
exports.middleware = middleware;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "csrf",
|
|
3
|
+
"title": "CSRF保护中间件",
|
|
4
|
+
"description": "防止跨站请求伪造攻击,提供安全的令牌验证机制",
|
|
5
|
+
"version": "1.0",
|
|
6
|
+
"type": "web",
|
|
7
|
+
"process_type": "common_before",
|
|
8
|
+
"sort": 20,
|
|
9
|
+
"state": 1,
|
|
10
|
+
"config": {
|
|
11
|
+
"enable": true,
|
|
12
|
+
"cookie_name": "csrf_token",
|
|
13
|
+
"header_name": "X-CSRF-Token",
|
|
14
|
+
"form_field": "_csrf",
|
|
15
|
+
"max_age": 3600000,
|
|
16
|
+
"ignore_methods": ["GET", "HEAD", "OPTIONS"],
|
|
17
|
+
"ignore_paths": ["/api/user/sign_in", "/user/login", "/login", "/admin/login"],
|
|
18
|
+
"generate_new": true,
|
|
19
|
+
"check_origin": true,
|
|
20
|
+
"log": true,
|
|
21
|
+
"block": true,
|
|
22
|
+
"allowed_origins": []
|
|
23
|
+
}
|
|
24
|
+
}
|