@point3/logto-module 1.0.23 → 1.1.0
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/.idea/copilot.data.migration.ask2agent.xml +6 -0
- package/.idea/inspectionProfiles/Project_Default.xml +7 -0
- package/.idea/misc.xml +7 -0
- package/.idea/modules.xml +8 -0
- package/.idea/point3-logto-module.iml +9 -0
- package/.idea/vcs.xml +6 -0
- package/.serena/project.yml +87 -0
- package/README.md +124 -80
- package/client/config.ts +62 -0
- package/client/logto-login-session.ts +8 -17
- package/client/m2m-client.ts +14 -24
- package/client/oauth-client.ts +18 -32
- package/dist/client/config.d.ts +23 -0
- package/dist/client/logto-login-session.d.ts +2 -3
- package/dist/client/logto-login-session.js +4 -13
- package/dist/client/logto-login-session.js.map +1 -1
- package/dist/client/m2m-client.d.ts +3 -3
- package/dist/client/m2m-client.js +11 -19
- package/dist/client/m2m-client.js.map +1 -1
- package/dist/client/oauth-client.d.ts +4 -4
- package/dist/client/oauth-client.js +16 -22
- package/dist/client/oauth-client.js.map +1 -1
- package/dist/module.d.ts +24 -1
- package/dist/module.js +124 -23
- package/dist/module.js.map +1 -1
- package/dist/token/verifier.d.ts +3 -3
- package/dist/token/verifier.js +5 -14
- package/dist/token/verifier.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/module.ts +264 -80
- package/package.json +1 -1
- package/token/verifier.ts +8 -17
package/module.ts
CHANGED
|
@@ -1,93 +1,237 @@
|
|
|
1
|
-
import { DynamicModule,
|
|
1
|
+
import { DynamicModule, LoggerService, Provider, Type } from '@nestjs/common';
|
|
2
2
|
import { ConfigModule, ConfigService } from '@nestjs/config';
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
3
|
+
import {
|
|
4
|
+
LogtoLoggerServiceToken,
|
|
5
|
+
LogtoLoginSessionToken,
|
|
6
|
+
LogtoM2MClientToken,
|
|
7
|
+
OAuthClient,
|
|
8
|
+
OAuthClientToken,
|
|
9
|
+
LogtoLoginSession,
|
|
10
|
+
LogtoM2MClient,
|
|
11
|
+
Prompt,
|
|
11
12
|
} from './client';
|
|
12
13
|
import { LogtoTokenVerifier, LogtoTokenVerifierToken } from './token';
|
|
13
14
|
import { LogtoTokenGuard, LogtoTokenGuardToken } from './stateless';
|
|
14
15
|
|
|
16
|
+
/** LogtoModule 옵션 주입 토큰 */
|
|
17
|
+
export const LOGTO_MODULE_OPTIONS = Symbol('LOGTO_MODULE_OPTIONS');
|
|
18
|
+
|
|
19
|
+
/** 로거 설정 */
|
|
20
|
+
export interface LogtoLoggerOptions {
|
|
21
|
+
/** 로거 모듈 (forRoot에서만 필요) */
|
|
22
|
+
module?: Type<any>;
|
|
23
|
+
/** 로거 서비스의 Injection Token */
|
|
24
|
+
token: Symbol | string;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/** forRoot 옵션 */
|
|
28
|
+
export interface LogtoModuleOptions {
|
|
29
|
+
/** 모듈을 전역으로 설정할지 여부 */
|
|
30
|
+
global?: boolean;
|
|
31
|
+
/** 클라이언트 기능 활성화 (OAuthClient, LogtoM2MClient, LogtoLoginSession) */
|
|
32
|
+
enableClient?: boolean;
|
|
33
|
+
/** 로거 설정 */
|
|
34
|
+
logger: LogtoLoggerOptions & { module: Type<any> };
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/** forRootAsync useFactory 반환 타입 */
|
|
38
|
+
export interface LogtoModuleFactoryOptions {
|
|
39
|
+
/** 클라이언트 기능 활성화 */
|
|
40
|
+
enableClient?: boolean;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/** forRootAsync 옵션 */
|
|
44
|
+
export interface LogtoModuleAsyncOptions {
|
|
45
|
+
/** 모듈을 전역으로 설정할지 여부 */
|
|
46
|
+
global?: boolean;
|
|
47
|
+
/** 의존 모듈 목록 (로거 모듈 포함) */
|
|
48
|
+
imports?: Type<any>[];
|
|
49
|
+
/** 로거 서비스의 Injection Token */
|
|
50
|
+
loggerToken: Symbol | string;
|
|
51
|
+
/** 옵션 팩토리 함수 */
|
|
52
|
+
useFactory: (...args: any[]) => LogtoModuleFactoryOptions | Promise<LogtoModuleFactoryOptions>;
|
|
53
|
+
/** 팩토리 함수에 주입할 의존성 */
|
|
54
|
+
inject?: any[];
|
|
55
|
+
}
|
|
56
|
+
|
|
15
57
|
/**
|
|
16
58
|
* LogtoModule
|
|
17
59
|
*
|
|
18
60
|
* Logto 인증 및 토큰 검증, 클라이언트 기능을 NestJS 모듈로 제공합니다.
|
|
19
61
|
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
* - **Stateful 모드 (`LOGTO_CLIENT=true`)**:
|
|
25
|
-
* 로그인/로그아웃 처리가 필요한 웹 애플리케이션이나, M2M 통신으로 Logto의 User/Role 관리 API를 사용해야 할 경우에 사용합니다.
|
|
26
|
-
* `OAuthClient`, `LogtoM2MClient` 등 모든 클라이언트 기능이 추가로 활성화됩니다.
|
|
62
|
+
* - **Stateless 모드 (enableClient=false)**:
|
|
63
|
+
* API 서버와 같이 토큰 검증만 필요한 경우 사용합니다.
|
|
64
|
+
* `@LogtoProtected()` 가드와 `LogtoTokenVerifier`만 활성화됩니다.
|
|
27
65
|
*
|
|
28
|
-
|
|
29
|
-
|
|
66
|
+
* - **Stateful 모드 (enableClient=true)**:
|
|
67
|
+
* 로그인/로그아웃 처리가 필요한 웹 애플리케이션이나,
|
|
68
|
+
* M2M 통신으로 Logto의 User/Role 관리 API를 사용해야 할 경우에 사용합니다.
|
|
69
|
+
* `OAuthClient`, `LogtoM2MClient` 등 모든 클라이언트 기능이 활성화됩니다.
|
|
70
|
+
*/
|
|
30
71
|
export class LogtoModule {
|
|
31
|
-
|
|
32
72
|
/**
|
|
33
|
-
*
|
|
73
|
+
* forRoot
|
|
34
74
|
*
|
|
35
|
-
*
|
|
75
|
+
* LogtoModule을 초기화합니다. (동기 설정)
|
|
36
76
|
*
|
|
37
|
-
* @param
|
|
38
|
-
* @param loggerToken - DI에 등록된 로거 서비스의 Injection Token
|
|
39
|
-
* @param global - 모듈을 전역(Global)으로 설정할지 여부 (기본값: false)
|
|
77
|
+
* @param options - 모듈 설정 옵션
|
|
40
78
|
* @returns DynamicModule
|
|
41
79
|
*
|
|
42
80
|
* @example
|
|
43
|
-
* //
|
|
44
|
-
*
|
|
45
|
-
*
|
|
46
|
-
*
|
|
47
|
-
* import { LogtoModule } from 'point3-logto-module';
|
|
48
|
-
* // `MyLoggerModule`과 `MY_LOGGER_TOKEN`은 사용하는 로깅 시스템에 맞게 구현해야 합니다.
|
|
49
|
-
* import { MyLoggerModule, MY_LOGGER_TOKEN } from './common/logger';
|
|
50
|
-
*
|
|
51
|
-
* \@Module({
|
|
52
|
-
* imports: [
|
|
53
|
-
* // .env 파일을 읽기 위해 ConfigModule을 먼저 임포트합니다.
|
|
54
|
-
* ConfigModule.forRoot({ isGlobal: true }),
|
|
55
|
-
*
|
|
56
|
-
* // LogtoModule을 설정합니다.
|
|
57
|
-
* // `LOGTO_CLIENT` 환경변수 값에 따라 필요한 서비스만 주입됩니다.
|
|
58
|
-
* LogtoModule.forLogger(MyLoggerModule, MY_LOGGER_TOKEN, true),
|
|
59
|
-
* ],
|
|
81
|
+
* // Stateless 모드: 토큰 검증만 필요한 경우
|
|
82
|
+
* LogtoModule.forRoot({
|
|
83
|
+
* global: true,
|
|
84
|
+
* logger: { module: WinstonLoggerModule, token: 'LOGGER' },
|
|
60
85
|
* })
|
|
61
|
-
* export class AppModule {}
|
|
62
86
|
*
|
|
63
87
|
* @example
|
|
64
|
-
* //
|
|
88
|
+
* // Stateful 모드: 클라이언트 기능이 필요한 경우
|
|
89
|
+
* LogtoModule.forRoot({
|
|
90
|
+
* global: true,
|
|
91
|
+
* enableClient: true,
|
|
92
|
+
* logger: { module: WinstonLoggerModule, token: 'LOGGER' },
|
|
93
|
+
* })
|
|
94
|
+
*/
|
|
95
|
+
static forRoot(options: LogtoModuleOptions): DynamicModule {
|
|
96
|
+
const { global = false, enableClient = false, logger } = options;
|
|
97
|
+
|
|
98
|
+
const baseProviders: Provider[] = [
|
|
99
|
+
{
|
|
100
|
+
provide: LogtoLoggerServiceToken,
|
|
101
|
+
useExisting: logger.token,
|
|
102
|
+
},
|
|
103
|
+
{
|
|
104
|
+
provide: LogtoTokenVerifierToken,
|
|
105
|
+
useFactory: (configService: ConfigService) => {
|
|
106
|
+
return new LogtoTokenVerifier({
|
|
107
|
+
jwksUri: configService.get<string>('LOGTO_JWKS_URI') ?? 'http://localhost:3001/oidc/jwks',
|
|
108
|
+
issuer: configService.getOrThrow<string>('LOGTO_AUTH_ISSUER'),
|
|
109
|
+
});
|
|
110
|
+
},
|
|
111
|
+
inject: [ConfigService],
|
|
112
|
+
},
|
|
113
|
+
{
|
|
114
|
+
provide: LogtoTokenGuardToken,
|
|
115
|
+
useClass: LogtoTokenGuard,
|
|
116
|
+
},
|
|
117
|
+
];
|
|
118
|
+
|
|
119
|
+
const clientProviders: Provider[] = enableClient
|
|
120
|
+
? [
|
|
121
|
+
{
|
|
122
|
+
provide: OAuthClientToken,
|
|
123
|
+
useFactory: (configService: ConfigService, loggerService: LoggerService) => {
|
|
124
|
+
return new OAuthClient(
|
|
125
|
+
{
|
|
126
|
+
endpoint: configService.getOrThrow<string>('LOGTO_AUTH_ENDPOINT'),
|
|
127
|
+
clientId: configService.getOrThrow<string>('LOGTO_CLIENT_ID'),
|
|
128
|
+
clientSecret: configService.getOrThrow<string>('LOGTO_CLIENT_SECRET'),
|
|
129
|
+
resources: [configService.getOrThrow<string>('LOGTO_RESOURCES')],
|
|
130
|
+
scopes: configService.getOrThrow<string>('LOGTO_SCOPES').split(','),
|
|
131
|
+
prompt: configService.getOrThrow<string>('LOGTO_PROMPT') as Prompt,
|
|
132
|
+
redirectUri: configService.getOrThrow<string>('LOGTO_REDIRECT_URI'),
|
|
133
|
+
signInUri: configService.getOrThrow<string>('LOGTO_SIGN_IN_URI'),
|
|
134
|
+
dashboardSignInUri: configService.get<string>('LOGTO_DASHBOARD_SIGN_IN_URI'),
|
|
135
|
+
},
|
|
136
|
+
loggerService,
|
|
137
|
+
);
|
|
138
|
+
},
|
|
139
|
+
inject: [ConfigService, LogtoLoggerServiceToken],
|
|
140
|
+
},
|
|
141
|
+
{
|
|
142
|
+
provide: LogtoLoginSessionToken,
|
|
143
|
+
useFactory: (
|
|
144
|
+
configService: ConfigService,
|
|
145
|
+
loggerService: LoggerService,
|
|
146
|
+
oauthClient: OAuthClient,
|
|
147
|
+
) => {
|
|
148
|
+
return new LogtoLoginSession(
|
|
149
|
+
configService.getOrThrow<string>('LOGTO_M2M_API_URL'),
|
|
150
|
+
loggerService,
|
|
151
|
+
oauthClient,
|
|
152
|
+
);
|
|
153
|
+
},
|
|
154
|
+
inject: [ConfigService, LogtoLoggerServiceToken, OAuthClientToken],
|
|
155
|
+
},
|
|
156
|
+
{
|
|
157
|
+
provide: LogtoM2MClientToken,
|
|
158
|
+
useFactory: (
|
|
159
|
+
configService: ConfigService,
|
|
160
|
+
tokenVerifier: LogtoTokenVerifier,
|
|
161
|
+
loggerService: LoggerService,
|
|
162
|
+
) => {
|
|
163
|
+
return new LogtoM2MClient(
|
|
164
|
+
{
|
|
165
|
+
endpoint: configService.getOrThrow<string>('LOGTO_AUTH_ENDPOINT'),
|
|
166
|
+
clientId: configService.getOrThrow<string>('LOGTO_M2M_CLIENT_ID'),
|
|
167
|
+
clientSecret: configService.getOrThrow<string>('LOGTO_M2M_CLIENT_SECRET'),
|
|
168
|
+
resource: configService.getOrThrow<string>('LOGTO_M2M_RESOURCE'),
|
|
169
|
+
apiUrl: configService.getOrThrow<string>('LOGTO_M2M_API_URL'),
|
|
170
|
+
scopes: ['all'],
|
|
171
|
+
},
|
|
172
|
+
tokenVerifier,
|
|
173
|
+
loggerService,
|
|
174
|
+
);
|
|
175
|
+
},
|
|
176
|
+
inject: [ConfigService, LogtoTokenVerifierToken, LogtoLoggerServiceToken],
|
|
177
|
+
},
|
|
178
|
+
]
|
|
179
|
+
: [];
|
|
180
|
+
|
|
181
|
+
const providers = [...baseProviders, ...clientProviders];
|
|
182
|
+
|
|
183
|
+
return {
|
|
184
|
+
module: LogtoModule,
|
|
185
|
+
global,
|
|
186
|
+
imports: [ConfigModule, logger.module],
|
|
187
|
+
providers,
|
|
188
|
+
exports: providers,
|
|
189
|
+
};
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
/**
|
|
193
|
+
* forRootAsync
|
|
194
|
+
*
|
|
195
|
+
* LogtoModule을 초기화합니다. (비동기 설정, ConfigService 활용 가능)
|
|
65
196
|
*
|
|
66
|
-
*
|
|
67
|
-
*
|
|
197
|
+
* @param options - 비동기 모듈 설정 옵션
|
|
198
|
+
* @returns DynamicModule
|
|
68
199
|
*
|
|
69
|
-
*
|
|
70
|
-
*
|
|
71
|
-
*
|
|
72
|
-
*
|
|
73
|
-
*
|
|
74
|
-
*
|
|
75
|
-
*
|
|
76
|
-
*
|
|
200
|
+
* @example
|
|
201
|
+
* LogtoModule.forRootAsync({
|
|
202
|
+
* global: true,
|
|
203
|
+
* imports: [WinstonLoggerModule],
|
|
204
|
+
* loggerToken: 'LOGGER',
|
|
205
|
+
* useFactory: (configService: ConfigService) => ({
|
|
206
|
+
* enableClient: configService.get('LOGTO_CLIENT') === 'true',
|
|
207
|
+
* }),
|
|
208
|
+
* inject: [ConfigService],
|
|
209
|
+
* })
|
|
77
210
|
*/
|
|
78
|
-
static
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
211
|
+
static forRootAsync(options: LogtoModuleAsyncOptions): DynamicModule {
|
|
212
|
+
const { global = false, imports = [], loggerToken, useFactory, inject = [] } = options;
|
|
213
|
+
|
|
214
|
+
const asyncOptionsProvider: Provider = {
|
|
215
|
+
provide: LOGTO_MODULE_OPTIONS,
|
|
216
|
+
useFactory,
|
|
217
|
+
inject,
|
|
218
|
+
};
|
|
219
|
+
|
|
83
220
|
const baseProviders: Provider[] = [
|
|
221
|
+
asyncOptionsProvider,
|
|
84
222
|
{
|
|
85
223
|
provide: LogtoLoggerServiceToken,
|
|
86
224
|
useExisting: loggerToken,
|
|
87
225
|
},
|
|
88
226
|
{
|
|
89
227
|
provide: LogtoTokenVerifierToken,
|
|
90
|
-
|
|
228
|
+
useFactory: (configService: ConfigService) => {
|
|
229
|
+
return new LogtoTokenVerifier({
|
|
230
|
+
jwksUri: configService.get<string>('LOGTO_JWKS_URI') ?? 'http://localhost:3001/oidc/jwks',
|
|
231
|
+
issuer: configService.getOrThrow<string>('LOGTO_AUTH_ISSUER'),
|
|
232
|
+
});
|
|
233
|
+
},
|
|
234
|
+
inject: [ConfigService],
|
|
91
235
|
},
|
|
92
236
|
{
|
|
93
237
|
provide: LogtoTokenGuardToken,
|
|
@@ -95,49 +239,89 @@ export class LogtoModule {
|
|
|
95
239
|
},
|
|
96
240
|
];
|
|
97
241
|
|
|
98
|
-
const
|
|
242
|
+
const clientProviders: Provider[] = [
|
|
99
243
|
{
|
|
100
244
|
provide: OAuthClientToken,
|
|
101
|
-
useFactory: (
|
|
102
|
-
|
|
103
|
-
|
|
245
|
+
useFactory: (
|
|
246
|
+
opts: LogtoModuleFactoryOptions,
|
|
247
|
+
configService: ConfigService,
|
|
248
|
+
loggerService: LoggerService,
|
|
249
|
+
) => {
|
|
250
|
+
if (opts.enableClient) {
|
|
251
|
+
return new OAuthClient(
|
|
252
|
+
{
|
|
253
|
+
endpoint: configService.getOrThrow<string>('LOGTO_AUTH_ENDPOINT'),
|
|
254
|
+
clientId: configService.getOrThrow<string>('LOGTO_CLIENT_ID'),
|
|
255
|
+
clientSecret: configService.getOrThrow<string>('LOGTO_CLIENT_SECRET'),
|
|
256
|
+
resources: [configService.getOrThrow<string>('LOGTO_RESOURCES')],
|
|
257
|
+
scopes: configService.getOrThrow<string>('LOGTO_SCOPES').split(','),
|
|
258
|
+
prompt: configService.getOrThrow<string>('LOGTO_PROMPT') as Prompt,
|
|
259
|
+
redirectUri: configService.getOrThrow<string>('LOGTO_REDIRECT_URI'),
|
|
260
|
+
signInUri: configService.getOrThrow<string>('LOGTO_SIGN_IN_URI'),
|
|
261
|
+
dashboardSignInUri: configService.get<string>('LOGTO_DASHBOARD_SIGN_IN_URI'),
|
|
262
|
+
},
|
|
263
|
+
loggerService,
|
|
264
|
+
);
|
|
104
265
|
}
|
|
105
266
|
return null;
|
|
106
267
|
},
|
|
107
|
-
inject: [ConfigService, LogtoLoggerServiceToken],
|
|
268
|
+
inject: [LOGTO_MODULE_OPTIONS, ConfigService, LogtoLoggerServiceToken],
|
|
108
269
|
},
|
|
109
270
|
{
|
|
110
271
|
provide: LogtoLoginSessionToken,
|
|
111
|
-
useFactory: (
|
|
112
|
-
|
|
113
|
-
|
|
272
|
+
useFactory: (
|
|
273
|
+
opts: LogtoModuleFactoryOptions,
|
|
274
|
+
configService: ConfigService,
|
|
275
|
+
loggerService: LoggerService,
|
|
276
|
+
oauthClient: OAuthClient,
|
|
277
|
+
) => {
|
|
278
|
+
if (opts.enableClient) {
|
|
279
|
+
return new LogtoLoginSession(
|
|
280
|
+
configService.getOrThrow<string>('LOGTO_M2M_API_URL'),
|
|
281
|
+
loggerService,
|
|
282
|
+
oauthClient,
|
|
283
|
+
);
|
|
114
284
|
}
|
|
115
285
|
return null;
|
|
116
286
|
},
|
|
117
|
-
inject: [ConfigService, LogtoLoggerServiceToken, OAuthClientToken],
|
|
287
|
+
inject: [LOGTO_MODULE_OPTIONS, ConfigService, LogtoLoggerServiceToken, OAuthClientToken],
|
|
118
288
|
},
|
|
119
289
|
{
|
|
120
290
|
provide: LogtoM2MClientToken,
|
|
121
|
-
useFactory: (
|
|
122
|
-
|
|
123
|
-
|
|
291
|
+
useFactory: (
|
|
292
|
+
opts: LogtoModuleFactoryOptions,
|
|
293
|
+
configService: ConfigService,
|
|
294
|
+
tokenVerifier: LogtoTokenVerifier,
|
|
295
|
+
loggerService: LoggerService,
|
|
296
|
+
) => {
|
|
297
|
+
if (opts.enableClient) {
|
|
298
|
+
return new LogtoM2MClient(
|
|
299
|
+
{
|
|
300
|
+
endpoint: configService.getOrThrow<string>('LOGTO_AUTH_ENDPOINT'),
|
|
301
|
+
clientId: configService.getOrThrow<string>('LOGTO_M2M_CLIENT_ID'),
|
|
302
|
+
clientSecret: configService.getOrThrow<string>('LOGTO_M2M_CLIENT_SECRET'),
|
|
303
|
+
resource: configService.getOrThrow<string>('LOGTO_M2M_RESOURCE'),
|
|
304
|
+
apiUrl: configService.getOrThrow<string>('LOGTO_M2M_API_URL'),
|
|
305
|
+
scopes: ['all'],
|
|
306
|
+
},
|
|
307
|
+
tokenVerifier,
|
|
308
|
+
loggerService,
|
|
309
|
+
);
|
|
124
310
|
}
|
|
125
311
|
return null;
|
|
126
312
|
},
|
|
127
|
-
inject: [ConfigService, LogtoTokenVerifierToken, LogtoLoggerServiceToken],
|
|
313
|
+
inject: [LOGTO_MODULE_OPTIONS, ConfigService, LogtoTokenVerifierToken, LogtoLoggerServiceToken],
|
|
128
314
|
},
|
|
129
315
|
];
|
|
130
|
-
|
|
131
|
-
const providers = [...baseProviders, ...
|
|
316
|
+
|
|
317
|
+
const providers = [...baseProviders, ...clientProviders];
|
|
132
318
|
|
|
133
319
|
return {
|
|
134
320
|
module: LogtoModule,
|
|
135
|
-
global
|
|
136
|
-
imports: [
|
|
137
|
-
|
|
138
|
-
],
|
|
139
|
-
providers: providers,
|
|
321
|
+
global,
|
|
322
|
+
imports: [ConfigModule, ...imports],
|
|
323
|
+
providers,
|
|
140
324
|
exports: providers,
|
|
141
325
|
};
|
|
142
326
|
}
|
|
143
|
-
}
|
|
327
|
+
}
|
package/package.json
CHANGED
package/token/verifier.ts
CHANGED
|
@@ -1,17 +1,14 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { ConfigService } from "@nestjs/config";
|
|
1
|
+
import { Injectable, UnauthorizedException } from "@nestjs/common";
|
|
3
2
|
import { jwtVerify, createRemoteJWKSet } from "jose";
|
|
4
3
|
|
|
4
|
+
import { LogtoVerifierConfig } from "../client/config";
|
|
5
5
|
import * as token from "./access-token";
|
|
6
6
|
|
|
7
7
|
export const LogtoTokenVerifierToken = Symbol.for("LogtoTokenVerifier");
|
|
8
8
|
|
|
9
9
|
@Injectable()
|
|
10
10
|
export class LogtoTokenVerifier {
|
|
11
|
-
constructor(
|
|
12
|
-
@Inject(ConfigService)
|
|
13
|
-
private readonly configService: ConfigService
|
|
14
|
-
) { }
|
|
11
|
+
constructor(private readonly config: LogtoVerifierConfig) { }
|
|
15
12
|
|
|
16
13
|
/**
|
|
17
14
|
* 토큰을 검증하고 필요에 따라 필수 스코프와 역할을 확인합니다.
|
|
@@ -26,12 +23,9 @@ export class LogtoTokenVerifier {
|
|
|
26
23
|
public async verifyToken(token: string, requiredScopes?: string[], requiredRoles?: string[]): Promise<token.AccessTokenPayload> {
|
|
27
24
|
if (!token) throw new UnauthorizedException('엑세스 토큰이 존재하지 않습니다.');
|
|
28
25
|
|
|
29
|
-
const jwksUri = this.configService.get<string>("LOGTO_JWKS_URI") ?? 'http://localhost:3001/oidc/jwks';
|
|
30
|
-
const issuer = this.configService.get<string>("LOGTO_AUTH_ISSUER");
|
|
31
|
-
|
|
32
26
|
const { payload } = await jwtVerify(
|
|
33
|
-
token, createRemoteJWKSet(new URL(jwksUri)),
|
|
34
|
-
{ issuer }
|
|
27
|
+
token, createRemoteJWKSet(new URL(this.config.jwksUri)),
|
|
28
|
+
{ issuer: this.config.issuer }
|
|
35
29
|
);
|
|
36
30
|
|
|
37
31
|
const tokenPayload = payload as token.AccessTokenPayload;
|
|
@@ -50,13 +44,10 @@ export class LogtoTokenVerifier {
|
|
|
50
44
|
* @returns id token 페이로드입니다.
|
|
51
45
|
*/
|
|
52
46
|
public async verifyIdToken(token: string): Promise<token.IdTokenPayload> {
|
|
53
|
-
const jwksUri = process.env.LOGTO_JWKS_URI ?? 'http://localhost:3001/oidc/jwks';
|
|
54
|
-
const issuer = process.env.LOGTO_AUTH_ISSUER;
|
|
55
|
-
|
|
56
47
|
const { payload } = await jwtVerify(
|
|
57
48
|
token,
|
|
58
|
-
createRemoteJWKSet(new URL(jwksUri)),
|
|
59
|
-
{ issuer }
|
|
49
|
+
createRemoteJWKSet(new URL(this.config.jwksUri)),
|
|
50
|
+
{ issuer: this.config.issuer }
|
|
60
51
|
);
|
|
61
52
|
return payload as token.IdTokenPayload;
|
|
62
53
|
}
|
|
@@ -97,4 +88,4 @@ export class LogtoTokenVerifier {
|
|
|
97
88
|
private hasInsufficientRoles(requiredRoles: string[] | undefined, userRoles: string[]): boolean {
|
|
98
89
|
return !!(requiredRoles && requiredRoles.length > 0 && !requiredRoles.some(role => userRoles.includes(role)));
|
|
99
90
|
}
|
|
100
|
-
}
|
|
91
|
+
}
|