@point3/logto-module 1.0.23 → 1.1.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/.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
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
<component name="InspectionProjectProfileManager">
|
|
2
|
+
<profile version="1.0">
|
|
3
|
+
<option name="myName" value="Project Default" />
|
|
4
|
+
<inspection_tool class="Eslint" enabled="true" level="WARNING" enabled_by_default="true" />
|
|
5
|
+
<inspection_tool class="TsLint" enabled="true" level="WARNING" enabled_by_default="true" />
|
|
6
|
+
</profile>
|
|
7
|
+
</component>
|
package/.idea/misc.xml
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<project version="4">
|
|
3
|
+
<component name="ProjectModuleManager">
|
|
4
|
+
<modules>
|
|
5
|
+
<module fileurl="file://$PROJECT_DIR$/.idea/point3-logto-module.iml" filepath="$PROJECT_DIR$/.idea/point3-logto-module.iml" />
|
|
6
|
+
</modules>
|
|
7
|
+
</component>
|
|
8
|
+
</project>
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<module type="JAVA_MODULE" version="4">
|
|
3
|
+
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
|
4
|
+
<exclude-output />
|
|
5
|
+
<content url="file://$MODULE_DIR$" />
|
|
6
|
+
<orderEntry type="inheritedJdk" />
|
|
7
|
+
<orderEntry type="sourceFolder" forTests="false" />
|
|
8
|
+
</component>
|
|
9
|
+
</module>
|
package/.idea/vcs.xml
ADDED
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
# list of languages for which language servers are started; choose from:
|
|
2
|
+
# al bash clojure cpp csharp csharp_omnisharp
|
|
3
|
+
# dart elixir elm erlang fortran fsharp
|
|
4
|
+
# go groovy haskell java julia kotlin
|
|
5
|
+
# lua markdown nix pascal perl php
|
|
6
|
+
# powershell python python_jedi r rego ruby
|
|
7
|
+
# ruby_solargraph rust scala swift terraform toml
|
|
8
|
+
# typescript typescript_vts yaml zig
|
|
9
|
+
# Note:
|
|
10
|
+
# - For C, use cpp
|
|
11
|
+
# - For JavaScript, use typescript
|
|
12
|
+
# - For Free Pascal / Lazarus, use pascal
|
|
13
|
+
# Special requirements:
|
|
14
|
+
# - csharp: Requires the presence of a .sln file in the project folder.
|
|
15
|
+
# - pascal: Requires Free Pascal Compiler (fpc) and optionally Lazarus.
|
|
16
|
+
# When using multiple languages, the first language server that supports a given file will be used for that file.
|
|
17
|
+
# The first language is the default language and the respective language server will be used as a fallback.
|
|
18
|
+
# Note that when using the JetBrains backend, language servers are not used and this list is correspondingly ignored.
|
|
19
|
+
languages:
|
|
20
|
+
- typescript
|
|
21
|
+
|
|
22
|
+
# the encoding used by text files in the project
|
|
23
|
+
# For a list of possible encodings, see https://docs.python.org/3.11/library/codecs.html#standard-encodings
|
|
24
|
+
encoding: "utf-8"
|
|
25
|
+
|
|
26
|
+
# whether to use the project's gitignore file to ignore files
|
|
27
|
+
# Added on 2025-04-07
|
|
28
|
+
ignore_all_files_in_gitignore: true
|
|
29
|
+
|
|
30
|
+
# list of additional paths to ignore
|
|
31
|
+
# same syntax as gitignore, so you can use * and **
|
|
32
|
+
# Was previously called `ignored_dirs`, please update your config if you are using that.
|
|
33
|
+
# Added (renamed) on 2025-04-07
|
|
34
|
+
ignored_paths: []
|
|
35
|
+
|
|
36
|
+
# whether the project is in read-only mode
|
|
37
|
+
# If set to true, all editing tools will be disabled and attempts to use them will result in an error
|
|
38
|
+
# Added on 2025-04-18
|
|
39
|
+
read_only: false
|
|
40
|
+
|
|
41
|
+
# list of tool names to exclude. We recommend not excluding any tools, see the readme for more details.
|
|
42
|
+
# Below is the complete list of tools for convenience.
|
|
43
|
+
# To make sure you have the latest list of tools, and to view their descriptions,
|
|
44
|
+
# execute `uv run scripts/print_tool_overview.py`.
|
|
45
|
+
#
|
|
46
|
+
# * `activate_project`: Activates a project by name.
|
|
47
|
+
# * `check_onboarding_performed`: Checks whether project onboarding was already performed.
|
|
48
|
+
# * `create_text_file`: Creates/overwrites a file in the project directory.
|
|
49
|
+
# * `delete_lines`: Deletes a range of lines within a file.
|
|
50
|
+
# * `delete_memory`: Deletes a memory from Serena's project-specific memory store.
|
|
51
|
+
# * `execute_shell_command`: Executes a shell command.
|
|
52
|
+
# * `find_referencing_code_snippets`: Finds code snippets in which the symbol at the given location is referenced.
|
|
53
|
+
# * `find_referencing_symbols`: Finds symbols that reference the symbol at the given location (optionally filtered by type).
|
|
54
|
+
# * `find_symbol`: Performs a global (or local) search for symbols with/containing a given name/substring (optionally filtered by type).
|
|
55
|
+
# * `get_current_config`: Prints the current configuration of the agent, including the active and available projects, tools, contexts, and modes.
|
|
56
|
+
# * `get_symbols_overview`: Gets an overview of the top-level symbols defined in a given file.
|
|
57
|
+
# * `initial_instructions`: Gets the initial instructions for the current project.
|
|
58
|
+
# Should only be used in settings where the system prompt cannot be set,
|
|
59
|
+
# e.g. in clients you have no control over, like Claude Desktop.
|
|
60
|
+
# * `insert_after_symbol`: Inserts content after the end of the definition of a given symbol.
|
|
61
|
+
# * `insert_at_line`: Inserts content at a given line in a file.
|
|
62
|
+
# * `insert_before_symbol`: Inserts content before the beginning of the definition of a given symbol.
|
|
63
|
+
# * `list_dir`: Lists files and directories in the given directory (optionally with recursion).
|
|
64
|
+
# * `list_memories`: Lists memories in Serena's project-specific memory store.
|
|
65
|
+
# * `onboarding`: Performs onboarding (identifying the project structure and essential tasks, e.g. for testing or building).
|
|
66
|
+
# * `prepare_for_new_conversation`: Provides instructions for preparing for a new conversation (in order to continue with the necessary context).
|
|
67
|
+
# * `read_file`: Reads a file within the project directory.
|
|
68
|
+
# * `read_memory`: Reads the memory with the given name from Serena's project-specific memory store.
|
|
69
|
+
# * `remove_project`: Removes a project from the Serena configuration.
|
|
70
|
+
# * `replace_lines`: Replaces a range of lines within a file with new content.
|
|
71
|
+
# * `replace_symbol_body`: Replaces the full definition of a symbol.
|
|
72
|
+
# * `restart_language_server`: Restarts the language server, may be necessary when edits not through Serena happen.
|
|
73
|
+
# * `search_for_pattern`: Performs a search for a pattern in the project.
|
|
74
|
+
# * `summarize_changes`: Provides instructions for summarizing the changes made to the codebase.
|
|
75
|
+
# * `switch_modes`: Activates modes by providing a list of their names
|
|
76
|
+
# * `think_about_collected_information`: Thinking tool for pondering the completeness of collected information.
|
|
77
|
+
# * `think_about_task_adherence`: Thinking tool for determining whether the agent is still on track with the current task.
|
|
78
|
+
# * `think_about_whether_you_are_done`: Thinking tool for determining whether the task is truly completed.
|
|
79
|
+
# * `write_memory`: Writes a named memory (for future reference) to Serena's project-specific memory store.
|
|
80
|
+
excluded_tools: []
|
|
81
|
+
|
|
82
|
+
# initial prompt for the project. It will always be given to the LLM upon activating the project
|
|
83
|
+
# (contrary to the memories, which are loaded on demand).
|
|
84
|
+
initial_prompt: ""
|
|
85
|
+
|
|
86
|
+
project_name: "point3-logto-module"
|
|
87
|
+
included_optional_tools: []
|
package/README.md
CHANGED
|
@@ -1,27 +1,27 @@
|
|
|
1
1
|
# point3-logto-module
|
|
2
2
|
|
|
3
|
-
NestJS 기반 Logto 인증/권한 통합 모듈
|
|
3
|
+
NestJS 기반 Logto 인증/권한 통합 모듈
|
|
4
4
|
(서버/클라이언트, M2M, 사용자/역할 관리, OAuth, DI 기반 확장성 제공)
|
|
5
5
|
|
|
6
6
|
---
|
|
7
7
|
|
|
8
8
|
## 📦 개요
|
|
9
9
|
|
|
10
|
-
`@point3-logto-module`은 [Logto](https://logto.io/) 인증 시스템을 NestJS 환경에서 손쉽게 통합할 수 있도록 설계된 모듈 번들입니다.
|
|
10
|
+
`@point3-logto-module`은 [Logto](https://logto.io/) 인증 시스템을 NestJS 환경에서 손쉽게 통합할 수 있도록 설계된 모듈 번들입니다.
|
|
11
11
|
OAuth, M2M(Machine-to-Machine), 사용자/역할 관리, 토큰 검증, 인증 가드 등 인증/권한 관련 기능을 일관된 DI 패턴으로 제공합니다.
|
|
12
12
|
|
|
13
13
|
### 동작 모드
|
|
14
14
|
|
|
15
|
-
`
|
|
15
|
+
`enableClient` 옵션에 따라 두 가지 모드로 동작합니다:
|
|
16
16
|
|
|
17
|
-
- **Stateless 모드 (`
|
|
17
|
+
- **Stateless 모드 (`enableClient: false` 또는 미설정)**:
|
|
18
18
|
- API 서버와 같이 토큰 검증만 필요한 경우 사용
|
|
19
19
|
- `@LogtoProtected()` 가드와 `LogtoTokenVerifier`만 활성화
|
|
20
|
-
- 필수 환경변수: `
|
|
20
|
+
- 필수 환경변수: `LOGTO_AUTH_ISSUER`만 필요 (LOGTO_JWKS_URI는 선택)
|
|
21
21
|
|
|
22
|
-
- **Stateful 모드 (`
|
|
22
|
+
- **Stateful 모드 (`enableClient: true`)**:
|
|
23
23
|
- 로그인/로그아웃 처리가 필요한 웹 애플리케이션이나 M2M 통신이 필요한 경우 사용
|
|
24
|
-
- `OAuthClient`, `LogtoM2MClient` 등 모든 클라이언트 기능 활성화
|
|
24
|
+
- `OAuthClient`, `LogtoM2MClient`, `LogtoLoginSession` 등 모든 클라이언트 기능 활성화
|
|
25
25
|
- 추가 환경변수 필요 (OAuth, M2M 관련)
|
|
26
26
|
|
|
27
27
|
### 주요 특징
|
|
@@ -30,6 +30,7 @@ OAuth, M2M(Machine-to-Machine), 사용자/역할 관리, 토큰 검증, 인증
|
|
|
30
30
|
- **NestJS Dynamic Module 패턴**: 환경/구성에 따라 동적으로 모듈 생성
|
|
31
31
|
- **Global 모듈 지원**: 애플리케이션 전체에서 사용할 수 있는 글로벌 모듈로 설정 가능
|
|
32
32
|
- **실제 서비스에서 검증된 인증/권한 관리 기능**: OAuth, M2M, 사용자/역할 관리, 토큰 검증, 인증 가드 등
|
|
33
|
+
- **Fail-fast 환경변수 검증**: 필수 환경변수가 없으면 모듈 초기화 시 즉시 에러 발생
|
|
33
34
|
|
|
34
35
|
---
|
|
35
36
|
|
|
@@ -37,9 +38,9 @@ OAuth, M2M(Machine-to-Machine), 사용자/역할 관리, 토큰 검증, 인증
|
|
|
37
38
|
|
|
38
39
|
### 1. LogtoModule (Dynamic Module)
|
|
39
40
|
|
|
40
|
-
-
|
|
41
|
-
- `
|
|
42
|
-
- global
|
|
41
|
+
- 외부 로거 모듈과 토큰을 주입받아, Logto 인증/권한 기능을 번들로 제공
|
|
42
|
+
- `LogtoModule.forRoot(options)` 또는 `LogtoModule.forRootAsync(options)` 패턴으로 사용
|
|
43
|
+
- `global` 옵션을 `true`로 설정하면 애플리케이션 전체에서 사용 가능한 글로벌 모듈로 등록
|
|
43
44
|
|
|
44
45
|
### 2. 핵심 서비스/토큰
|
|
45
46
|
|
|
@@ -51,7 +52,13 @@ OAuth, M2M(Machine-to-Machine), 사용자/역할 관리, 토큰 검증, 인증
|
|
|
51
52
|
- **LogtoLoggerServiceToken**: DI로 주입받는 외부 로거 토큰
|
|
52
53
|
- **stateless**: 미들웨어/핸들러 기반의 Stateless 인증/인가 유틸리티 및 가드 제공
|
|
53
54
|
|
|
54
|
-
### 3.
|
|
55
|
+
### 3. Config 인터페이스
|
|
56
|
+
|
|
57
|
+
- **LogtoVerifierConfig**: 토큰 검증 설정 (jwksUri, issuer)
|
|
58
|
+
- **LogtoOAuthConfig**: OAuth 클라이언트 설정 (endpoint, clientId, clientSecret, resources, scopes, prompt, redirectUri, signInUri, dashboardSignInUri)
|
|
59
|
+
- **LogtoM2MConfig**: M2M 클라이언트 설정 (endpoint, clientId, clientSecret, resource, apiUrl, scopes)
|
|
60
|
+
|
|
61
|
+
### 4. 주요 타입/설정
|
|
55
62
|
|
|
56
63
|
- **LogtoConfig**: 인증/권한 기능을 위한 환경설정 객체
|
|
57
64
|
- **Prompt, GrantType**: OAuth 표준 파라미터 Enum
|
|
@@ -90,7 +97,9 @@ export const MY_LOGGER_TOKEN = Symbol.for('LOGGER');
|
|
|
90
97
|
export class MyLoggerModule {}
|
|
91
98
|
```
|
|
92
99
|
|
|
93
|
-
### 2. AppModule에서 LogtoModule
|
|
100
|
+
### 2. AppModule에서 LogtoModule 설정
|
|
101
|
+
|
|
102
|
+
#### forRoot (동기 설정)
|
|
94
103
|
|
|
95
104
|
```ts
|
|
96
105
|
import { Module } from '@nestjs/common';
|
|
@@ -102,9 +111,51 @@ import { MyLoggerModule, MY_LOGGER_TOKEN } from './my-logger.module';
|
|
|
102
111
|
imports: [
|
|
103
112
|
// 환경변수를 먼저 로드
|
|
104
113
|
ConfigModule.forRoot({ isGlobal: true }),
|
|
105
|
-
|
|
106
|
-
//
|
|
107
|
-
logto.module.LogtoModule.
|
|
114
|
+
|
|
115
|
+
// Stateless 모드: 토큰 검증만 필요한 경우
|
|
116
|
+
logto.module.LogtoModule.forRoot({
|
|
117
|
+
global: true,
|
|
118
|
+
logger: {
|
|
119
|
+
module: MyLoggerModule,
|
|
120
|
+
token: MY_LOGGER_TOKEN,
|
|
121
|
+
},
|
|
122
|
+
}),
|
|
123
|
+
|
|
124
|
+
// Stateful 모드: 클라이언트 기능이 필요한 경우
|
|
125
|
+
// logto.module.LogtoModule.forRoot({
|
|
126
|
+
// global: true,
|
|
127
|
+
// enableClient: true,
|
|
128
|
+
// logger: {
|
|
129
|
+
// module: MyLoggerModule,
|
|
130
|
+
// token: MY_LOGGER_TOKEN,
|
|
131
|
+
// },
|
|
132
|
+
// }),
|
|
133
|
+
],
|
|
134
|
+
})
|
|
135
|
+
export class AppModule {}
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
#### forRootAsync (비동기 설정)
|
|
139
|
+
|
|
140
|
+
```ts
|
|
141
|
+
import { Module } from '@nestjs/common';
|
|
142
|
+
import { ConfigModule, ConfigService } from '@nestjs/config';
|
|
143
|
+
import * as logto from '@point3/logto-module';
|
|
144
|
+
import { MyLoggerModule, MY_LOGGER_TOKEN } from './my-logger.module';
|
|
145
|
+
|
|
146
|
+
@Module({
|
|
147
|
+
imports: [
|
|
148
|
+
ConfigModule.forRoot({ isGlobal: true }),
|
|
149
|
+
|
|
150
|
+
logto.module.LogtoModule.forRootAsync({
|
|
151
|
+
global: true,
|
|
152
|
+
imports: [MyLoggerModule],
|
|
153
|
+
loggerToken: MY_LOGGER_TOKEN,
|
|
154
|
+
useFactory: (configService: ConfigService) => ({
|
|
155
|
+
enableClient: configService.get('LOGTO_CLIENT') === 'true',
|
|
156
|
+
}),
|
|
157
|
+
inject: [ConfigService],
|
|
158
|
+
}),
|
|
108
159
|
],
|
|
109
160
|
})
|
|
110
161
|
export class AppModule {}
|
|
@@ -148,13 +199,13 @@ export class AuthService {
|
|
|
148
199
|
|
|
149
200
|
### 4. stateless 네임스페이스 활용 예시
|
|
150
201
|
|
|
151
|
-
> ⚠️ **중요한 주의사항**
|
|
152
|
-
> `requiredScopes`와 `requiredRoles`에 사용되는 모든 스코프와 역할은 **반드시 Logto 관리 콘솔에서 먼저 정의되어야 합니다**.
|
|
153
|
-
>
|
|
202
|
+
> ⚠️ **중요한 주의사항**
|
|
203
|
+
> `requiredScopes`와 `requiredRoles`에 사용되는 모든 스코프와 역할은 **반드시 Logto 관리 콘솔에서 먼저 정의되어야 합니다**.
|
|
204
|
+
>
|
|
154
205
|
> - **스코프(Scopes)**: Logto 콘솔의 API Resources → 해당 리소스 → Scopes에서 정의
|
|
155
|
-
> - **역할(Roles)**: Logto 콘솔의 User Management → Roles에서 정의
|
|
206
|
+
> - **역할(Roles)**: Logto 콘솔의 User Management → Roles에서 정의
|
|
156
207
|
> - **역할-스코프 연결**: 각 역할에 필요한 스코프들을 Logto 콘솔에서 할당
|
|
157
|
-
>
|
|
208
|
+
>
|
|
158
209
|
> 코드에서 사용하는 스코프/역할 이름이 Logto에 정의되지 않았다면 토큰 검증이 실패합니다.
|
|
159
210
|
|
|
160
211
|
#### 4-1. LogtoProtected 데코레이터를 사용한 라우트 보호
|
|
@@ -263,19 +314,19 @@ export class CustomLogtoGuard extends stateless.LogtoTokenGuard {
|
|
|
263
314
|
async canActivate(context: ExecutionContext): Promise<boolean> {
|
|
264
315
|
// 기본 토큰 검증 수행
|
|
265
316
|
const isValid = await super.canActivate(context);
|
|
266
|
-
|
|
317
|
+
|
|
267
318
|
if (!isValid) return false;
|
|
268
319
|
|
|
269
320
|
// 추가 커스텀 로직
|
|
270
321
|
const request = context.switchToHttp().getRequest();
|
|
271
322
|
const user = request.user;
|
|
272
|
-
|
|
323
|
+
|
|
273
324
|
// 예: 특정 시간대에만 접근 허용
|
|
274
325
|
const currentHour = new Date().getHours();
|
|
275
326
|
if (currentHour < 9 || currentHour > 18) {
|
|
276
327
|
return false;
|
|
277
328
|
}
|
|
278
|
-
|
|
329
|
+
|
|
279
330
|
return true;
|
|
280
331
|
}
|
|
281
332
|
}
|
|
@@ -338,54 +389,44 @@ export class TypedController {
|
|
|
338
389
|
|
|
339
390
|
---
|
|
340
391
|
|
|
341
|
-
##
|
|
392
|
+
## 🗂️ 환경변수 목록 및 설명
|
|
342
393
|
|
|
343
|
-
|
|
344
|
-
const config: LogtoConfig = {
|
|
345
|
-
endpoint: 'https://auth.example.com/oidc',
|
|
346
|
-
appId: 'my-client-id',
|
|
347
|
-
appSecret: 'my-client-secret',
|
|
348
|
-
grantType: GrantType.AuthorizationCode,
|
|
349
|
-
scopes: ['openid', 'profile', 'email'],
|
|
350
|
-
resources: ['https://api.example.com'],
|
|
351
|
-
prompt: Prompt.Login,
|
|
352
|
-
redirectUri: 'https://myapp.com/callback',
|
|
353
|
-
};
|
|
354
|
-
```
|
|
394
|
+
### Stateless 모드 (토큰 검증만)
|
|
355
395
|
|
|
356
|
-
|
|
396
|
+
| 환경변수명 | 필수 | 설명 | 예시 값 |
|
|
397
|
+
|-----------|------|------|---------|
|
|
398
|
+
| LOGTO_AUTH_ISSUER | ✅ | JWT 발급자(iss) | https://auth.example.com/oidc |
|
|
399
|
+
| LOGTO_JWKS_URI | ❌ | JWT 검증용 JWKS 엔드포인트 (기본값: http://localhost:3001/oidc/jwks) | https://auth.example.com/oidc/jwks |
|
|
357
400
|
|
|
358
|
-
|
|
401
|
+
### Stateful 모드 (`enableClient: true`)
|
|
402
|
+
|
|
403
|
+
#### OAuth 클라이언트 관련 (OAuthClient, LogtoLoginSession)
|
|
359
404
|
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
|
363
|
-
|
|
364
|
-
|
|
|
365
|
-
|
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
|
375
|
-
|
|
376
|
-
|
|
|
377
|
-
|
|
|
378
|
-
|
|
|
379
|
-
|
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
> ⚠️ **중요**:
|
|
387
|
-
> - Stateless 모드(기본값): `LOGTO_JWKS_URI`와 `LOGTO_AUTH_ISSUER`만 설정하면 토큰 검증 기능을 사용할 수 있습니다.
|
|
388
|
-
> - Stateful 모드: `LOGTO_CLIENT=true`로 설정하고 OAuth/M2M 관련 환경변수를 추가로 설정해야 합니다.
|
|
405
|
+
| 환경변수명 | 필수 | 설명 | 예시 값 |
|
|
406
|
+
|-----------|------|------|---------|
|
|
407
|
+
| LOGTO_AUTH_ENDPOINT | ✅ | Logto 인증 서버 OIDC 엔드포인트 | https://auth.example.com/oidc |
|
|
408
|
+
| LOGTO_CLIENT_ID | ✅ | OAuth 클라이언트 ID | my-client-id |
|
|
409
|
+
| LOGTO_CLIENT_SECRET | ✅ | OAuth 클라이언트 시크릿 | my-client-secret |
|
|
410
|
+
| LOGTO_RESOURCES | ✅ | 접근할 리소스 서버 | https://api.example.com |
|
|
411
|
+
| LOGTO_SCOPES | ✅ | 요청할 OAuth 스코프 (쉼표로 구분) | openid,profile,email |
|
|
412
|
+
| LOGTO_PROMPT | ✅ | OAuth prompt 파라미터 | login |
|
|
413
|
+
| LOGTO_REDIRECT_URI | ✅ | 인증 후 리다이렉트될 URI | https://myapp.com/callback |
|
|
414
|
+
| LOGTO_SIGN_IN_URI | ✅ | 기본 로그인 URI | https://auth.example.com |
|
|
415
|
+
| LOGTO_DASHBOARD_SIGN_IN_URI | ❌ | 대시보드 로그인 URI (선택) | https://dashboard.example.com |
|
|
416
|
+
|
|
417
|
+
#### M2M 클라이언트 관련 (LogtoM2MClient)
|
|
418
|
+
|
|
419
|
+
| 환경변수명 | 필수 | 설명 | 예시 값 |
|
|
420
|
+
|-----------|------|------|---------|
|
|
421
|
+
| LOGTO_M2M_CLIENT_ID | ✅ | M2M 인증용 클라이언트 ID | my-m2m-client-id |
|
|
422
|
+
| LOGTO_M2M_CLIENT_SECRET | ✅ | M2M 인증용 클라이언트 시크릿 | my-m2m-client-secret |
|
|
423
|
+
| LOGTO_M2M_RESOURCE | ✅ | M2M 인증용 리소스 | https://api.example.com |
|
|
424
|
+
| LOGTO_M2M_API_URL | ✅ | M2M API 서버의 base URL | https://api.example.com/api |
|
|
425
|
+
|
|
426
|
+
> ⚠️ **중요**:
|
|
427
|
+
> - 필수 환경변수(✅)가 설정되지 않으면 모듈 초기화 시 **즉시 에러가 발생**합니다.
|
|
428
|
+
> - Stateless 모드에서는 `LOGTO_AUTH_ISSUER`만 필수입니다.
|
|
429
|
+
> - Stateful 모드에서는 위 표의 모든 필수 환경변수가 설정되어야 합니다.
|
|
389
430
|
|
|
390
431
|
---
|
|
391
432
|
|
|
@@ -399,24 +440,27 @@ const config: LogtoConfig = {
|
|
|
399
440
|
|
|
400
441
|
## ❓ FAQ
|
|
401
442
|
|
|
402
|
-
- **Q. 로거 토큰이 다르면 어떻게 하나요?**
|
|
403
|
-
→ `
|
|
443
|
+
- **Q. 로거 토큰이 다르면 어떻게 하나요?**
|
|
444
|
+
→ `forRoot`의 `logger.token`에 원하는 토큰(Symbol)을 넘기면 됩니다.
|
|
404
445
|
|
|
405
|
-
- **Q. 환경변수 기반 설정은 어떻게 하나요?**
|
|
406
|
-
→
|
|
446
|
+
- **Q. 환경변수 기반 설정은 어떻게 하나요?**
|
|
447
|
+
→ LogtoModule이 내부적으로 `ConfigService`를 사용하여 환경변수를 자동으로 읽습니다. `ConfigModule.forRoot({ isGlobal: true })`가 먼저 import되어 있어야 합니다.
|
|
407
448
|
|
|
408
|
-
- **Q. 인증/권한 외에 사용자/역할 관리도 가능한가요?**
|
|
449
|
+
- **Q. 인증/권한 외에 사용자/역할 관리도 가능한가요?**
|
|
409
450
|
→ 네, `LogtoM2MClient`를 통해 사용자/역할 생성, 조회, 수정, 삭제, 할당 등 모든 관리가 가능합니다.
|
|
410
451
|
|
|
411
|
-
- **Q. Stateless 모드와 Stateful 모드의 차이는 무엇인가요?**
|
|
412
|
-
→ Stateless 모드는 토큰 검증만 필요한 API 서버에 적합하며,
|
|
413
|
-
→ Stateful 모드는 `
|
|
452
|
+
- **Q. Stateless 모드와 Stateful 모드의 차이는 무엇인가요?**
|
|
453
|
+
→ Stateless 모드는 토큰 검증만 필요한 API 서버에 적합하며, `LOGTO_AUTH_ISSUER`만 필수입니다.
|
|
454
|
+
→ Stateful 모드는 `enableClient: true`로 설정하여 로그인/로그아웃, M2M 통신 등 클라이언트 기능을 모두 사용할 수 있습니다.
|
|
455
|
+
|
|
456
|
+
- **Q. global 옵션은 언제 사용하나요?**
|
|
457
|
+
→ `global: true`로 설정하면 LogtoModule이 글로벌 모듈로 등록되어, 다른 모듈에서 별도의 import 없이 Logto 서비스들을 사용할 수 있습니다.
|
|
414
458
|
|
|
415
|
-
- **Q.
|
|
416
|
-
→
|
|
459
|
+
- **Q. 토큰 검증만 필요한데 모든 환경변수를 설정해야 하나요?**
|
|
460
|
+
→ 아니요. 토큰 검증만 필요하다면 `LOGTO_AUTH_ISSUER`만 설정하면 됩니다. `enableClient`를 설정하지 않거나 `false`로 설정하면 자동으로 Stateless 모드가 활성화됩니다.
|
|
417
461
|
|
|
418
|
-
- **Q.
|
|
419
|
-
→
|
|
462
|
+
- **Q. 필수 환경변수가 없으면 어떻게 되나요?**
|
|
463
|
+
→ 모듈 초기화 시점에 `ConfigService.getOrThrow()`를 사용하여 즉시 에러가 발생합니다. 이를 통해 런타임 오류를 사전에 방지할 수 있습니다.
|
|
420
464
|
|
|
421
465
|
---
|
|
422
466
|
|
|
@@ -436,4 +480,4 @@ const config: LogtoConfig = {
|
|
|
436
480
|
|
|
437
481
|
## 📝 라이선스
|
|
438
482
|
|
|
439
|
-
MIT
|
|
483
|
+
MIT
|
package/client/config.ts
CHANGED
|
@@ -77,3 +77,65 @@ export enum GrantType {
|
|
|
77
77
|
ClientCredentials = 'client_credentials',
|
|
78
78
|
RefreshToken = 'refresh_token',
|
|
79
79
|
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* LogtoVerifierConfig
|
|
83
|
+
*
|
|
84
|
+
* Stateless 모드에서 토큰 검증에 필요한 설정입니다.
|
|
85
|
+
* - jwksUri: JWKS 엔드포인트 URI
|
|
86
|
+
* - issuer: 토큰 발급자(issuer)
|
|
87
|
+
*/
|
|
88
|
+
export interface LogtoVerifierConfig {
|
|
89
|
+
/** JWKS 엔드포인트 URI */
|
|
90
|
+
jwksUri: string;
|
|
91
|
+
/** 토큰 발급자 (issuer) */
|
|
92
|
+
issuer: string;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* LogtoOAuthConfig
|
|
97
|
+
*
|
|
98
|
+
* OAuth 클라이언트 설정입니다.
|
|
99
|
+
* Authorization Code 플로우에서 사용됩니다.
|
|
100
|
+
*/
|
|
101
|
+
export interface LogtoOAuthConfig {
|
|
102
|
+
/** Logto 인증 서버의 엔드포인트 URL */
|
|
103
|
+
endpoint: string;
|
|
104
|
+
/** Logto 애플리케이션의 Client ID */
|
|
105
|
+
clientId: string;
|
|
106
|
+
/** Logto 애플리케이션의 Client Secret */
|
|
107
|
+
clientSecret: string;
|
|
108
|
+
/** 접근할 리소스 서버 목록 */
|
|
109
|
+
resources: string[];
|
|
110
|
+
/** 요청할 OAuth 스코프 목록 */
|
|
111
|
+
scopes: string[];
|
|
112
|
+
/** 인증 요청 시 사용할 prompt 파라미터 */
|
|
113
|
+
prompt: Prompt;
|
|
114
|
+
/** 인증 후 리다이렉트될 URI */
|
|
115
|
+
redirectUri: string;
|
|
116
|
+
/** 로그인 URI */
|
|
117
|
+
signInUri: string;
|
|
118
|
+
/** 대시보드 로그인 URI (선택) */
|
|
119
|
+
dashboardSignInUri?: string;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* LogtoM2MConfig
|
|
124
|
+
*
|
|
125
|
+
* M2M(Machine-to-Machine) 클라이언트 설정입니다.
|
|
126
|
+
* Client Credentials 플로우에서 사용됩니다.
|
|
127
|
+
*/
|
|
128
|
+
export interface LogtoM2MConfig {
|
|
129
|
+
/** Logto 인증 서버의 엔드포인트 URL */
|
|
130
|
+
endpoint: string;
|
|
131
|
+
/** M2M 애플리케이션의 Client ID */
|
|
132
|
+
clientId: string;
|
|
133
|
+
/** M2M 애플리케이션의 Client Secret */
|
|
134
|
+
clientSecret: string;
|
|
135
|
+
/** 접근할 리소스 서버 */
|
|
136
|
+
resource: string;
|
|
137
|
+
/** Logto Management API URL */
|
|
138
|
+
apiUrl: string;
|
|
139
|
+
/** 요청할 OAuth 스코프 목록 */
|
|
140
|
+
scopes: string[];
|
|
141
|
+
}
|
|
@@ -1,16 +1,13 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { ConfigService } from "@nestjs/config";
|
|
1
|
+
import { Injectable, LoggerService } from "@nestjs/common";
|
|
3
2
|
import axios, { AxiosResponse } from "axios";
|
|
4
3
|
import { axiosAdapter } from "point3-common-tool";
|
|
5
4
|
|
|
6
5
|
import {
|
|
7
6
|
OAuthClient,
|
|
8
|
-
OAuthClientToken,
|
|
9
7
|
SignInType,
|
|
10
8
|
} from "./oauth-client";
|
|
11
9
|
|
|
12
10
|
import {
|
|
13
|
-
LogtoLoggerServiceToken,
|
|
14
11
|
LogtoOAuthRESTTemplate,
|
|
15
12
|
} from "./types";
|
|
16
13
|
|
|
@@ -20,16 +17,16 @@ export const LogtoLoginSessionToken = Symbol.for("LogtoLoginSession");
|
|
|
20
17
|
@Injectable()
|
|
21
18
|
/**
|
|
22
19
|
* LogtoLoginSession
|
|
23
|
-
*
|
|
20
|
+
*
|
|
24
21
|
* Logto 인증 세션 플로우를 관리하는 클래스입니다.
|
|
25
22
|
* NestJS DI 환경에서 사용되며, Logto 로그인 과정의 각 단계를 API 호출로 래핑합니다.
|
|
26
|
-
*
|
|
23
|
+
*
|
|
27
24
|
* 주요 역할:
|
|
28
25
|
* - 로그인 세션 시작 및 세션 쿠키 관리
|
|
29
26
|
* - 인증 플로우(로그인 경험) 단계별 진행
|
|
30
27
|
* - 비밀번호 검증, 사용자 식별, 동의 및 제출 처리
|
|
31
28
|
* - 커스텀 로그인 플로우를 위한 저수준 제어 제공
|
|
32
|
-
*
|
|
29
|
+
*
|
|
33
30
|
* 사용 예시:
|
|
34
31
|
* const session = new LogtoLoginSession(...);
|
|
35
32
|
* await session.createSignInSession(...);
|
|
@@ -43,24 +40,18 @@ export class LogtoLoginSession {
|
|
|
43
40
|
|
|
44
41
|
/**
|
|
45
42
|
* LogtoLoginSession 생성자
|
|
46
|
-
*
|
|
43
|
+
*
|
|
44
|
+
* @param apiUrl - Logto API URL
|
|
47
45
|
* @param logger - 로깅 서비스
|
|
48
|
-
* @param configService - 환경설정 서비스
|
|
49
46
|
* @param oauthClient - OAuth 클라이언트 인스턴스
|
|
50
47
|
*/
|
|
51
48
|
constructor(
|
|
52
|
-
|
|
49
|
+
private readonly apiUrl: string,
|
|
53
50
|
private readonly logger: LoggerService,
|
|
54
|
-
|
|
55
|
-
@Inject(ConfigService)
|
|
56
|
-
private readonly configService: ConfigService,
|
|
57
|
-
|
|
58
|
-
@Inject(OAuthClientToken)
|
|
59
51
|
private readonly oauthClient: OAuthClient,
|
|
60
52
|
) {
|
|
61
53
|
// API 기본 URL로 REST 템플릿 초기화
|
|
62
|
-
|
|
63
|
-
this.apiRestTemplate = new LogtoOAuthRESTTemplate(this.logger, baseURL);
|
|
54
|
+
this.apiRestTemplate = new LogtoOAuthRESTTemplate(this.logger, apiUrl);
|
|
64
55
|
}
|
|
65
56
|
|
|
66
57
|
/**
|