@ahhaohho/auth-middleware 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.
- package/README.md +42 -6
- package/package.json +4 -4
- package/src/index.js +2 -1
- package/src/middleware/auth.js +94 -1
package/README.md
CHANGED
|
@@ -12,10 +12,10 @@ Shared authentication middleware with Passport.js for ahhaohho microservices.
|
|
|
12
12
|
|
|
13
13
|
## Installation
|
|
14
14
|
|
|
15
|
-
### Using
|
|
15
|
+
### Using npm (recommended)
|
|
16
16
|
|
|
17
17
|
```bash
|
|
18
|
-
npm install
|
|
18
|
+
npm install @ahhaohho/auth-middleware
|
|
19
19
|
```
|
|
20
20
|
|
|
21
21
|
Or add to `package.json`:
|
|
@@ -23,7 +23,23 @@ Or add to `package.json`:
|
|
|
23
23
|
```json
|
|
24
24
|
{
|
|
25
25
|
"dependencies": {
|
|
26
|
-
"@ahhaohho/auth-middleware": "
|
|
26
|
+
"@ahhaohho/auth-middleware": "^1.0.2"
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
### Using Git
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
npm install git+ssh://git@github.com:Future-Lab-META/auth-middleware.git#v1.0.2
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
Or add to `package.json`:
|
|
38
|
+
|
|
39
|
+
```json
|
|
40
|
+
{
|
|
41
|
+
"dependencies": {
|
|
42
|
+
"@ahhaohho/auth-middleware": "git+ssh://git@github.com:Future-Lab-META/auth-middleware.git#v1.0.2"
|
|
27
43
|
}
|
|
28
44
|
}
|
|
29
45
|
```
|
|
@@ -70,9 +86,19 @@ REDIS_PORT=6379
|
|
|
70
86
|
JWT_SECRET_NAME=your-secret-name
|
|
71
87
|
|
|
72
88
|
# Optional
|
|
73
|
-
ELASTICACHE_ENDPOINT=your-elasticache-endpoint # If using ElastiCache
|
|
89
|
+
ELASTICACHE_ENDPOINT=your-elasticache-endpoint # If using ElastiCache (auto-enables TLS)
|
|
90
|
+
REDIS_TLS=true # Force enable TLS for Redis connection
|
|
74
91
|
```
|
|
75
92
|
|
|
93
|
+
#### Redis Configuration Notes
|
|
94
|
+
|
|
95
|
+
- **REDIS_HOST**: If set, takes priority over ELASTICACHE_ENDPOINT
|
|
96
|
+
- **ELASTICACHE_ENDPOINT**: Used only when REDIS_HOST is not set
|
|
97
|
+
- **TLS Auto-detection**:
|
|
98
|
+
- TLS is automatically disabled for `localhost` and `127.0.0.1`
|
|
99
|
+
- TLS is automatically enabled when using ELASTICACHE_ENDPOINT (without REDIS_HOST)
|
|
100
|
+
- Use `REDIS_TLS=true` to force enable TLS for any host
|
|
101
|
+
|
|
76
102
|
## Architecture
|
|
77
103
|
|
|
78
104
|
### JWT Verification Flow
|
|
@@ -166,7 +192,7 @@ auth-middleware/
|
|
|
166
192
|
|
|
167
193
|
```bash
|
|
168
194
|
# Clone the repository
|
|
169
|
-
git clone git@github.com:
|
|
195
|
+
git clone git@github.com:Future-Lab-META/auth-middleware.git
|
|
170
196
|
cd auth-middleware
|
|
171
197
|
|
|
172
198
|
# Install dependencies
|
|
@@ -197,10 +223,20 @@ git push origin main --tags
|
|
|
197
223
|
|
|
198
224
|
### Using Specific Versions
|
|
199
225
|
|
|
226
|
+
```bash
|
|
227
|
+
# npm
|
|
228
|
+
npm install @ahhaohho/auth-middleware@1.0.2
|
|
229
|
+
|
|
230
|
+
# Git
|
|
231
|
+
npm install git+ssh://git@github.com:Future-Lab-META/auth-middleware.git#v1.0.2
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
Or in `package.json`:
|
|
235
|
+
|
|
200
236
|
```json
|
|
201
237
|
{
|
|
202
238
|
"dependencies": {
|
|
203
|
-
"@ahhaohho/auth-middleware": "
|
|
239
|
+
"@ahhaohho/auth-middleware": "1.0.2"
|
|
204
240
|
}
|
|
205
241
|
}
|
|
206
242
|
```
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ahhaohho/auth-middleware",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.3",
|
|
4
4
|
"description": "Shared authentication middleware with Passport.js for ahhaohho microservices",
|
|
5
5
|
"main": "src/index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -9,12 +9,12 @@
|
|
|
9
9
|
},
|
|
10
10
|
"repository": {
|
|
11
11
|
"type": "git",
|
|
12
|
-
"url": "git+https://github.com/
|
|
12
|
+
"url": "git+https://github.com/Future-Lab-META/auth-middleware.git"
|
|
13
13
|
},
|
|
14
14
|
"bugs": {
|
|
15
|
-
"url": "https://github.com/
|
|
15
|
+
"url": "https://github.com/Future-Lab-META/auth-middleware/issues"
|
|
16
16
|
},
|
|
17
|
-
"homepage": "https://github.com/
|
|
17
|
+
"homepage": "https://github.com/Future-Lab-META/auth-middleware#readme",
|
|
18
18
|
"publishConfig": {
|
|
19
19
|
"access": "public"
|
|
20
20
|
},
|
package/src/index.js
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* for ahhaohho microservices
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
-
const { authenticateJWT, authenticateRefresh, optionalAuth } = require('./middleware/auth');
|
|
8
|
+
const { authenticateJWT, authenticateRefresh, optionalAuth, authenticateHybrid } = require('./middleware/auth');
|
|
9
9
|
const { verifyTokenWithFallback, signToken, getCurrentSigningKey } = require('./utils/jwtValidator');
|
|
10
10
|
const { isBlacklisted, addToBlacklist, clearBlacklist } = require('./utils/blacklist');
|
|
11
11
|
const { getJwtKeys, invalidateCache } = require('./utils/secretManager');
|
|
@@ -17,6 +17,7 @@ module.exports = {
|
|
|
17
17
|
authenticateJWT,
|
|
18
18
|
authenticateRefresh,
|
|
19
19
|
optionalAuth,
|
|
20
|
+
authenticateHybrid,
|
|
20
21
|
|
|
21
22
|
// 유틸리티 함수 (필요시 직접 사용)
|
|
22
23
|
utils: {
|
package/src/middleware/auth.js
CHANGED
|
@@ -114,8 +114,101 @@ function optionalAuth(req, res, next) {
|
|
|
114
114
|
})(req, res, next);
|
|
115
115
|
}
|
|
116
116
|
|
|
117
|
+
/**
|
|
118
|
+
* Hybrid 인증 미들웨어 (access token 만료 시 refresh token으로 자동 갱신)
|
|
119
|
+
*
|
|
120
|
+
* 1. Access token 검증 시도
|
|
121
|
+
* 2. 실패하면 refresh token 확인
|
|
122
|
+
* 3. Refresh token이 유효하면 새 access token 생성하여 응답 헤더에 추가
|
|
123
|
+
*
|
|
124
|
+
* @example
|
|
125
|
+
* router.get('/protected', authenticateHybrid, (req, res) => {
|
|
126
|
+
* // req.user 사용 가능
|
|
127
|
+
* // 응답 헤더에 x-new-access-token이 있으면 클라이언트가 토큰 갱신해야 함
|
|
128
|
+
* res.json({ userId: req.user.userId });
|
|
129
|
+
* });
|
|
130
|
+
*/
|
|
131
|
+
async function authenticateHybrid(req, res, next) {
|
|
132
|
+
initializePassport();
|
|
133
|
+
|
|
134
|
+
// 1. Access token 검증 시도
|
|
135
|
+
passport.authenticate('jwt', { session: false }, async (err, user, info) => {
|
|
136
|
+
if (err) {
|
|
137
|
+
console.error('[@ahhaohho/auth-middleware] Hybrid auth error:', err.message);
|
|
138
|
+
return res.status(500).json({
|
|
139
|
+
error: 'Authentication error',
|
|
140
|
+
message: err.message
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
// Access token이 유효한 경우
|
|
145
|
+
if (user) {
|
|
146
|
+
req.user = user;
|
|
147
|
+
return next();
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
// 2. Access token이 유효하지 않은 경우, refresh token 확인
|
|
151
|
+
console.log('[@ahhaohho/auth-middleware] Access token invalid, trying refresh token...');
|
|
152
|
+
|
|
153
|
+
// Refresh token이 없으면 401 반환
|
|
154
|
+
if (!req.headers['refresh-token'] && !req.headers['refreshtoken']) {
|
|
155
|
+
return res.status(401).json({
|
|
156
|
+
error: 'Unauthorized',
|
|
157
|
+
message: 'Access token expired and no refresh token provided'
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
// 3. Refresh token 검증
|
|
162
|
+
passport.authenticate('refresh', { session: false }, async (refreshErr, refreshUser, refreshInfo) => {
|
|
163
|
+
if (refreshErr) {
|
|
164
|
+
console.error('[@ahhaohho/auth-middleware] Refresh token error:', refreshErr.message);
|
|
165
|
+
return res.status(500).json({
|
|
166
|
+
error: 'Token refresh error',
|
|
167
|
+
message: refreshErr.message
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
if (!refreshUser) {
|
|
172
|
+
return res.status(401).json({
|
|
173
|
+
error: 'Unauthorized',
|
|
174
|
+
message: 'Both access and refresh tokens are invalid'
|
|
175
|
+
});
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
// 4. 새 access token 생성
|
|
179
|
+
try {
|
|
180
|
+
const { signToken } = require('../utils/jwtValidator');
|
|
181
|
+
|
|
182
|
+
const tokenData = {
|
|
183
|
+
userId: refreshUser.userId,
|
|
184
|
+
userRole: refreshUser.userRole,
|
|
185
|
+
phoneNumber: refreshUser.phoneNumber
|
|
186
|
+
};
|
|
187
|
+
|
|
188
|
+
const newAccessToken = await signToken(tokenData, { expiresIn: '1h' });
|
|
189
|
+
|
|
190
|
+
console.log('[@ahhaohho/auth-middleware] ✅ New access token generated for userId:', refreshUser.userId);
|
|
191
|
+
|
|
192
|
+
// 5. 응답 헤더에 새 토큰 추가 (클라이언트가 이를 확인하여 저장)
|
|
193
|
+
res.setHeader('X-New-Access-Token', newAccessToken);
|
|
194
|
+
|
|
195
|
+
// 6. req.user 설정하고 계속 진행
|
|
196
|
+
req.user = refreshUser;
|
|
197
|
+
next();
|
|
198
|
+
} catch (tokenError) {
|
|
199
|
+
console.error('[@ahhaohho/auth-middleware] Failed to generate new token:', tokenError.message);
|
|
200
|
+
return res.status(500).json({
|
|
201
|
+
error: 'Token generation error',
|
|
202
|
+
message: tokenError.message
|
|
203
|
+
});
|
|
204
|
+
}
|
|
205
|
+
})(req, res, next);
|
|
206
|
+
})(req, res, next);
|
|
207
|
+
}
|
|
208
|
+
|
|
117
209
|
module.exports = {
|
|
118
210
|
authenticateJWT,
|
|
119
211
|
authenticateRefresh,
|
|
120
|
-
optionalAuth
|
|
212
|
+
optionalAuth,
|
|
213
|
+
authenticateHybrid
|
|
121
214
|
};
|