huxy-server 1.0.2 → 1.0.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.
Files changed (3) hide show
  1. package/README.md +29 -2
  2. package/package.json +2 -2
  3. package/src/index.js +53 -50
package/README.md CHANGED
@@ -52,8 +52,6 @@ startApp(config, (huxyConfig, app, httpServer) => {
52
52
  });
53
53
  ```
54
54
 
55
- `authToken` 默认值 '1234',如不需要鉴权可以设置环境变量 `AUTH_TOKEN=false` 或设置 `config = {authToken: false}`。
56
-
57
55
  ### 直接使用 `appProxy`
58
56
 
59
57
  也可直接使用 `appProxy`,只需传入你的服务 `app` 和代理 `config` 即可。
@@ -65,6 +63,35 @@ appProxy(app, config);
65
63
 
66
64
  ```
67
65
 
66
+ ### API 鉴权配置
67
+
68
+ 包含 2 种鉴权方式:
69
+
70
+ - apiKey:在请求头中 `x-api-key`或`x-huxy-auth` 里设置 `authToken` 值。
71
+ - jwt:在请求头中 `authorization` 里设置 `Bearer ${token}` 进行用户验证。
72
+
73
+ 默认不需要鉴权 `authToken: false` ,设置环境变量 `AUTH_TOKEN=false` 或 `config = {authToken: false}` 即可。如需鉴权选择上述 2 种方式中的一种即可,优先进行 `authToken` 认证。
74
+
75
+ 可配置免认证路由,如:`whitePathList: ['/health', '/status']` 。
76
+
77
+ 也可配置免认证 `authKeys` :如:`whiteAuthKeys: ['1234', '2234']` 。
78
+
79
+ 配置示例:
80
+
81
+ ```javascript
82
+ const config = {
83
+ // apiKey
84
+ authToken: '1234',
85
+ // jwt
86
+ secret: 'your-secret-key',
87
+ expiresIn: '30d',
88
+ issuer: 'your-app',
89
+ // white list
90
+ whiteAuthKeys: ['1234', '2234'],
91
+ whitePathList: ['/health', '/status'],
92
+ };
93
+ ```
94
+
68
95
  ### 环境变量
69
96
 
70
97
  项目支持以下环境变量:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "huxy-server",
3
- "version": "1.0.2",
3
+ "version": "1.0.3",
4
4
  "description": "一个精炼、高性能的 Express.js 服务器模板,为现代 Node.js 应用程序设计,提供灵活的功能和最佳实践。",
5
5
  "type": "module",
6
6
  "module": "./src/index.js",
@@ -36,7 +36,7 @@
36
36
  },
37
37
  "dependencies": {
38
38
  "http-proxy-middleware": "^3.0.5",
39
- "huxy-node-server": "^1.0.0",
39
+ "huxy-node-server": "^1.0.1",
40
40
  "jsonwebtoken": "^9.0.3"
41
41
  },
42
42
  "engines": {
package/src/index.js CHANGED
@@ -5,54 +5,54 @@ import {
5
5
  createLogger as ee,
6
6
  dateTime as te,
7
7
  localIPs as re,
8
- nodeArgs as oe,
9
- getEnvConfig as se,
8
+ nodeArgs as se,
9
+ getEnvConfig as oe,
10
10
  checkPort as ae,
11
11
  getDirName as ne,
12
12
  resolvePath as ie,
13
13
  } from 'huxy-node-server';
14
14
  import {createProxyMiddleware as I} from 'http-proxy-middleware';
15
15
  import {dateTime as $} from 'huxy-node-server';
16
- import j from 'jsonwebtoken';
17
- var f = (r, e = {secret, ...opt}) => j.verify(r, secret, opt);
16
+ import T from 'jsonwebtoken';
17
+ var f = (r, e = {secret, ...opt}) => T.verify(r, secret, opt);
18
18
  var x =
19
19
  (r = {}) =>
20
- (e, t, o) => {
21
- let n = e.headers.authorization;
22
- if (!n) return (e.log.warn('\u8BA4\u8BC1\u5931\u8D25: \u7F3A\u5C11\u8BA4\u8BC1\u4FE1\u606F'), t.status(401).json({message: '\u7F3A\u5C11\u8BA4\u8BC1\u4FE1\u606F'}));
23
- if (!n.startsWith('Bearer '))
20
+ (e, t, s) => {
21
+ let o = e.headers.authorization;
22
+ if (!o) return (e.log.warn('\u8BA4\u8BC1\u5931\u8D25: \u7F3A\u5C11\u8BA4\u8BC1\u4FE1\u606F'), t.status(401).json({message: '\u7F3A\u5C11\u8BA4\u8BC1\u4FE1\u606F'}));
23
+ if (!o.startsWith('Bearer '))
24
24
  return (e.log.warn('\u8BA4\u8BC1\u5931\u8D25: \u672A\u63D0\u4F9B\u6709\u6548\u8BA4\u8BC1\u4FE1\u606F'), t.status(401).json({message: '\u672A\u63D0\u4F9B\u6709\u6548\u8BA4\u8BC1\u4FE1\u606F'}));
25
- let a = n.split(' ')[1];
26
- if (!a) return (e.log.warn('\u8BA4\u8BC1\u5931\u8D25: \u8BBF\u95EE\u4EE4\u724C\u7F3A\u5931'), t.status(401).json({message: '\u8BBF\u95EE\u4EE4\u724C\u7F3A\u5931'}));
25
+ let n = o.split(' ')[1];
26
+ if (!n) return (e.log.warn('\u8BA4\u8BC1\u5931\u8D25: \u8BBF\u95EE\u4EE4\u724C\u7F3A\u5931'), t.status(401).json({message: '\u8BBF\u95EE\u4EE4\u724C\u7F3A\u5931'}));
27
27
  try {
28
- let s = f(a, r);
29
- (e.log.info(s, '\u8BA4\u8BC1\u6210\u529F'), (e.user = s), o());
30
- } catch (s) {
31
- return s.name === 'TokenExpiredError'
28
+ let a = f(n, r);
29
+ (e.log.info(a, '\u8BA4\u8BC1\u6210\u529F'), (e.user = a), s());
30
+ } catch (a) {
31
+ return a.name === 'TokenExpiredError'
32
32
  ? (e.log.warn({ip: e.ip}, '\u8BA4\u8BC1\u5931\u8D25: \u4EE4\u724C\u5DF2\u8FC7\u671F'), t.status(401).json({message: '\u4EE4\u724C\u5DF2\u8FC7\u671F'}))
33
- : s.name === 'JsonWebTokenError'
33
+ : a.name === 'JsonWebTokenError'
34
34
  ? (e.log.warn({ip: e.ip}, '\u8BA4\u8BC1\u5931\u8D25: \u65E0\u6548\u7684\u4EE4\u724C'), t.status(403).json({message: '\u65E0\u6548\u7684\u4EE4\u724C'}))
35
- : s instanceof AuthorizationError
36
- ? (e.log.warn({ip: e.ip}, `\u8BA4\u8BC1\u5931\u8D25: ${s.message}`), t.status(s.status).json({message: s.message}))
37
- : (e.log.warn({err: s, ip: e.ip}, '\u8BA4\u8BC1\u5931\u8D25: \u5185\u90E8\u670D\u52A1\u5668\u9519\u8BEF'), t.status(500).json({message: '\u5185\u90E8\u670D\u52A1\u5668\u9519\u8BEF'}));
35
+ : a instanceof AuthorizationError
36
+ ? (e.log.warn({ip: e.ip}, `\u8BA4\u8BC1\u5931\u8D25: ${a.message}`), t.status(a.status).json({message: a.message}))
37
+ : (e.log.warn({err: a, ip: e.ip}, '\u8BA4\u8BC1\u5931\u8D25: \u5185\u90E8\u670D\u52A1\u5668\u9519\u8BEF'), t.status(500).json({message: '\u5185\u90E8\u670D\u52A1\u5668\u9519\u8BEF'}));
38
38
  }
39
39
  };
40
40
  var v =
41
41
  ({whiteAuthKeys: r = [], whiteAuthPaths: e = [], config: t = {}}) =>
42
- (o, n, a) => {
43
- if (o.method === 'OPTIONS' || e.includes(o.path)) return a();
44
- let {authToken: s} = t;
45
- if (s === !1 || s === 'false') return a();
46
- let i = o.headers['x-huxy-auth'] || o.headers['x-api-key'];
47
- if ((i && i === s) || r.includes(i)) return a();
42
+ (s, o, n) => {
43
+ if (s.method === 'OPTIONS' || e.includes(s.path)) return n();
44
+ let {authToken: a} = t;
45
+ if (a === !1 || a === 'false') return n();
46
+ let i = s.headers['x-huxy-auth'] || s.headers['x-api-key'];
47
+ if ((i && i === a) || r.includes(i)) return n();
48
48
  let {secret: c, expiresIn: l, algorithm: p, issuer: h} = t;
49
- x({secret: c, expiresIn: l, algorithm: p, issuer: h})(o, n, a);
49
+ x({secret: c, expiresIn: l, algorithm: p, issuer: h})(s, o, n);
50
50
  },
51
51
  y = v;
52
52
  var H = ['x-powered-by', 'server'],
53
53
  w = (r, e) => {
54
54
  let t = new Headers(r);
55
- return (headersToRemove.forEach(o => t.delete(o)), t.set('Host', e), t.set('User-Agent', 'IHUXY-API/1.0'), t);
55
+ return (headersToRemove.forEach(s => t.delete(s)), t.set('Host', e), t.set('User-Agent', 'IHUXY-API/1.0'), t);
56
56
  },
57
57
  g = r => {
58
58
  let e = new Headers(r);
@@ -69,37 +69,40 @@ var R = r => Object.prototype.toString.call(r).slice(8, -1).toLowerCase(),
69
69
  A = (r, e) => E(r).map(t => ((t.prefix = `${e}${t.prefix ?? `/${t.name}`}`.replace('//', '/')), t)),
70
70
  u = r => (Array.isArray(r) ? r : []).filter(Boolean),
71
71
  P = (r, e) => ['/', '/health', e, ...u(r)].map(t => `${e}${t}`.replace('//', '/'));
72
- var S = ({target: r = 'http://localhost:11434', prefix: e = '/api', ...t} = {}, o = !1) => ({
72
+ var S = ({target: r = 'http://localhost:11434', prefix: e = '/api', ...t} = {}, s = !1) => ({
73
73
  target: r,
74
74
  pathRewrite: {[`^${e}`]: ''},
75
75
  changeOrigin: !0,
76
76
  selfHandleResponse: !1,
77
- onProxyReq: (n, a, s) => {
78
- !o && w(n.headers, r);
77
+ onProxyReq: (o, n, a) => {
78
+ !s && w(o.headers, r);
79
79
  },
80
- onProxyRes: (n, a, s) => {
81
- !o && g(n.headers);
80
+ onProxyRes: (o, n, a) => {
81
+ !s && g(o.headers);
82
82
  },
83
- onError: (n, a, s) => {
84
- (a.log.error({err: n}, '\u4EE3\u7406\u9519\u8BEF'), s.headersSent || s.status(502).json({error: '\u7F51\u5173\u9519\u8BEF'}));
83
+ onError: (o, n, a) => {
84
+ (n.log.error({err: o}, '\u4EE3\u7406\u9519\u8BEF'), a.headersSent || a.status(502).json({error: '\u7F51\u5173\u9519\u8BEF'}));
85
85
  },
86
86
  ...t,
87
87
  }),
88
88
  k = (r, e) => {
89
- let t = {status: 'OK', message: `API \u670D\u52A1\u5668\u8FD0\u884C\u4E2D -> ${e}`, timestamp: $(), uptime: process.uptime(), memoryUsage: process.memoryUsage()};
90
- r.get(`${e}/health`.replace('//', '/'), (o, n) => {
91
- n.status(200).json(t);
92
- });
89
+ let t = {status: 'OK', message: `API \u670D\u52A1\u5668\u8FD0\u884C\u4E2D \u{1F449} ${e}`, timestamp: $(), uptime: process.uptime(), memoryUsage: process.memoryUsage()};
90
+ (r.get(e, (s, o) => {
91
+ o.status(200).json(t);
92
+ }),
93
+ r.get(`${e}/health`.replace('//', '/'), (s, o) => {
94
+ o.status(200).json(t);
95
+ }));
93
96
  },
94
97
  C = (r, e = {}, t) => {
95
- let {apiPrefix: o, proxys: n = [], whiteAuthKeys: a = [], whitePathList: s = [], preserve: i = !1} = e,
96
- c = A(n, o);
98
+ let {apiPrefix: s, proxys: o = [], whiteAuthKeys: n = [], whitePathList: a = [], preserve: i = !1} = e,
99
+ c = A(o, s);
97
100
  if (!c.length) return;
98
- (t.info(`\u{1F4DD} API \u63A5\u53E3\u5730\u5740: http://${e.host}:${e.port}${o}`), k(r, o));
99
- let l = y({whiteAuthKeys: u(a), whitePathList: P(s, o), config: e});
101
+ (t.info(`\u{1F4DD} API \u63A5\u53E3\u5730\u5740: http://${e.host}:${e.port}${s}`), k(r, s));
102
+ let l = y({whiteAuthKeys: u(n), whitePathList: P(a, s), config: e});
100
103
  c.map(({prefix: p, target: h}) => {
101
- let T = S({prefix: p, target: h}, i);
102
- (r.use(p, l, I(T)), t.info(`\u2705 \u4EE3\u7406\u4E2D ${p} -> ${h}`));
104
+ let j = S({prefix: p, target: h}, i);
105
+ (r.use(p, l, I(j)), t.info(`\u2705 \u4EE3\u7406\u4E2D ${p} \u{1F449} ${h}`));
103
106
  });
104
107
  },
105
108
  d = C;
@@ -107,7 +110,7 @@ var O = {
107
110
  port: parseInt(process.env.PORT || '8080', 10),
108
111
  host: process.env.HOST || 'localhost',
109
112
  apiPrefix: process.env.API_PREFIX || '/api',
110
- authToken: '1234',
113
+ authToken: !1,
111
114
  proxys: [],
112
115
  whitePathList: ['/health'],
113
116
  algorithm: 'HS256',
@@ -117,13 +120,13 @@ var O = {
117
120
  },
118
121
  m = O;
119
122
  var M = (r, e) =>
120
- W({...m, ...r}, async (t, o, n, a) => {
121
- (await e?.(t, o, n, a), d(o, t, a));
123
+ W({...m, ...r}, async (t, s, o, n) => {
124
+ (await e?.(t, s, o, n), d(s, t, n));
122
125
  }),
123
126
  he = M,
124
127
  le = (r, e) =>
125
- L({...m, ...r}, async (t, o, n, a) => {
126
- (await e?.(t, o, n, a), d(o, t, a));
128
+ L({...m, ...r}, async (t, s, o, n) => {
129
+ (await e?.(t, s, o, n), d(s, t, n));
127
130
  });
128
131
  export {
129
132
  d as appProxy,
@@ -132,10 +135,10 @@ export {
132
135
  te as dateTime,
133
136
  he as default,
134
137
  ne as getDirName,
135
- se as getEnvConfig,
138
+ oe as getEnvConfig,
136
139
  re as localIPs,
137
140
  q as logger,
138
- oe as nodeArgs,
141
+ se as nodeArgs,
139
142
  ie as resolvePath,
140
143
  M as startApp,
141
144
  W as startServer,