@ahhaohho/auth-middleware 2.2.1 → 2.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/package.json +1 -1
- package/src/middleware/auth.js +9 -37
- package/src/utils/secretManager.js +30 -3
package/package.json
CHANGED
package/src/middleware/auth.js
CHANGED
|
@@ -35,18 +35,10 @@ function authenticateJWT(req, res, next) {
|
|
|
35
35
|
initializePassport();
|
|
36
36
|
|
|
37
37
|
passport.authenticate('jwt', { session: false }, (err, user, info) => {
|
|
38
|
-
if (err) {
|
|
39
|
-
console.error('[@ahhaohho/auth-middleware] Authentication error:', err.message);
|
|
40
|
-
return res.status(500).json({
|
|
41
|
-
error: 'Authentication error',
|
|
42
|
-
message: err.message
|
|
43
|
-
});
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
if (!user) {
|
|
38
|
+
if (err || !user) {
|
|
47
39
|
return res.status(401).json({
|
|
48
40
|
error: 'Unauthorized',
|
|
49
|
-
message: info?.message || 'Invalid or expired token'
|
|
41
|
+
message: err?.message || info?.message || 'Invalid or expired token'
|
|
50
42
|
});
|
|
51
43
|
}
|
|
52
44
|
|
|
@@ -74,18 +66,10 @@ function authenticateRefresh(req, res, next) {
|
|
|
74
66
|
initializePassport();
|
|
75
67
|
|
|
76
68
|
passport.authenticate('refresh', { session: false }, (err, user, info) => {
|
|
77
|
-
if (err) {
|
|
78
|
-
console.error('[@ahhaohho/auth-middleware] Refresh token error:', err.message);
|
|
79
|
-
return res.status(500).json({
|
|
80
|
-
error: 'Token refresh error',
|
|
81
|
-
message: err.message
|
|
82
|
-
});
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
if (!user) {
|
|
69
|
+
if (err || !user) {
|
|
86
70
|
return res.status(401).json({
|
|
87
71
|
error: 'Invalid refresh token',
|
|
88
|
-
message: info?.message || 'Invalid or expired refresh token'
|
|
72
|
+
message: err?.message || info?.message || 'Invalid or expired refresh token'
|
|
89
73
|
});
|
|
90
74
|
}
|
|
91
75
|
|
|
@@ -148,15 +132,12 @@ async function authenticateHybrid(req, res, next) {
|
|
|
148
132
|
// 1. Access token 검증 시도
|
|
149
133
|
passport.authenticate('jwt', { session: false }, async (err, user, info) => {
|
|
150
134
|
if (err) {
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
error: 'Authentication error',
|
|
154
|
-
message: err.message
|
|
155
|
-
});
|
|
135
|
+
// Access token 검증 에러는 refresh token 시도로 넘어감
|
|
136
|
+
console.log('[@ahhaohho/auth-middleware] Access token error, trying refresh token...');
|
|
156
137
|
}
|
|
157
138
|
|
|
158
139
|
// Access token이 유효한 경우
|
|
159
|
-
if (user) {
|
|
140
|
+
if (!err && user) {
|
|
160
141
|
req.user = user;
|
|
161
142
|
|
|
162
143
|
// 하위 호환성: req.userId, req.userRole 설정
|
|
@@ -179,19 +160,10 @@ async function authenticateHybrid(req, res, next) {
|
|
|
179
160
|
|
|
180
161
|
// 3. Refresh token 검증
|
|
181
162
|
passport.authenticate('refresh', { session: false }, async (refreshErr, refreshUser, refreshInfo) => {
|
|
182
|
-
if (refreshErr) {
|
|
183
|
-
console.error('[@ahhaohho/auth-middleware] Refresh token error:', refreshErr.message);
|
|
184
|
-
return res.status(500).json({
|
|
185
|
-
error: 'Token refresh error',
|
|
186
|
-
message: refreshErr.message
|
|
187
|
-
});
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
if (!refreshUser) {
|
|
191
|
-
console.error('[@ahhaohho/auth-middleware] ❌ No refresh user found, returning 401');
|
|
163
|
+
if (refreshErr || !refreshUser) {
|
|
192
164
|
return res.status(401).json({
|
|
193
165
|
error: 'Unauthorized',
|
|
194
|
-
message: 'Both access and refresh tokens are invalid'
|
|
166
|
+
message: refreshErr?.message || 'Both access and refresh tokens are invalid'
|
|
195
167
|
});
|
|
196
168
|
}
|
|
197
169
|
|
|
@@ -46,7 +46,7 @@ class SecretManager {
|
|
|
46
46
|
return JSON.parse(cachedKeys);
|
|
47
47
|
}
|
|
48
48
|
|
|
49
|
-
// 2. AWS Secrets Manager에서 가져오기
|
|
49
|
+
// 2. AWS Secrets Manager에서 가져오기 (AWSCURRENT + AWSPREVIOUS)
|
|
50
50
|
console.log('[@ahhaohho/auth-middleware] Fetching JWT keys from AWS Secrets Manager');
|
|
51
51
|
const command = new GetSecretValueCommand({ SecretId: this.secretName });
|
|
52
52
|
const response = await this.client.send(command);
|
|
@@ -56,9 +56,36 @@ class SecretManager {
|
|
|
56
56
|
}
|
|
57
57
|
|
|
58
58
|
const secret = JSON.parse(response.SecretString);
|
|
59
|
+
const currentKey = secret.current || secret.jwt_secret_key || secret.dev;
|
|
60
|
+
|
|
61
|
+
// previous 키 결정: secret 내 previous 필드 → AWSPREVIOUS 버전 순서
|
|
62
|
+
let previousKey = secret.previous || null;
|
|
63
|
+
|
|
64
|
+
if (!previousKey) {
|
|
65
|
+
try {
|
|
66
|
+
const prevCommand = new GetSecretValueCommand({
|
|
67
|
+
SecretId: this.secretName,
|
|
68
|
+
VersionStage: 'AWSPREVIOUS'
|
|
69
|
+
});
|
|
70
|
+
const prevResponse = await this.client.send(prevCommand);
|
|
71
|
+
if (prevResponse.SecretString) {
|
|
72
|
+
const prevSecret = JSON.parse(prevResponse.SecretString);
|
|
73
|
+
const prevCandidate = prevSecret.current || prevSecret.jwt_secret_key || prevSecret.dev;
|
|
74
|
+
// 이전 키가 현재 키와 다를 때만 사용
|
|
75
|
+
if (prevCandidate && prevCandidate !== currentKey) {
|
|
76
|
+
previousKey = prevCandidate;
|
|
77
|
+
console.log('[@ahhaohho/auth-middleware] Using AWSPREVIOUS version as fallback key');
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
} catch (prevError) {
|
|
81
|
+
// AWSPREVIOUS가 없을 수 있음 (첫 시크릿이거나 로테이션 미사용)
|
|
82
|
+
console.log('[@ahhaohho/auth-middleware] No AWSPREVIOUS version available');
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
59
86
|
const keys = {
|
|
60
|
-
current:
|
|
61
|
-
previous:
|
|
87
|
+
current: currentKey,
|
|
88
|
+
previous: previousKey
|
|
62
89
|
};
|
|
63
90
|
|
|
64
91
|
// 3. Redis에 캐싱 (5분 TTL)
|