@things-factory/integration-label-studio 9.1.19

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 (152) hide show
  1. package/CHANGELOG.md +85 -0
  2. package/EXTERNAL_DATA_SOURCING.md +484 -0
  3. package/IMPLEMENTATION_GUIDE.md +469 -0
  4. package/INTEGRATION.md +279 -0
  5. package/README.md +1014 -0
  6. package/SETUP_GUIDE.md +577 -0
  7. package/TEST_GUIDE.md +387 -0
  8. package/UI_CUSTOMIZATION.md +395 -0
  9. package/USER_SYNC_GUIDE.md +514 -0
  10. package/client/bootstrap.ts +1 -0
  11. package/client/index.ts +1 -0
  12. package/client/label-studio-label-page.ts +52 -0
  13. package/client/label-studio-project-create.ts +216 -0
  14. package/client/label-studio-project-list.ts +214 -0
  15. package/client/label-studio-wrapper.ts +294 -0
  16. package/client/route.ts +15 -0
  17. package/client/tsconfig.json +13 -0
  18. package/config/config.development.js +124 -0
  19. package/config/config.production.js +182 -0
  20. package/dist-client/bootstrap.d.ts +1 -0
  21. package/dist-client/bootstrap.js +2 -0
  22. package/dist-client/bootstrap.js.map +1 -0
  23. package/dist-client/index.d.ts +1 -0
  24. package/dist-client/index.js +2 -0
  25. package/dist-client/index.js.map +1 -0
  26. package/dist-client/label-studio-label-page.d.ts +8 -0
  27. package/dist-client/label-studio-label-page.js +54 -0
  28. package/dist-client/label-studio-label-page.js.map +1 -0
  29. package/dist-client/label-studio-project-create.d.ts +16 -0
  30. package/dist-client/label-studio-project-create.js +235 -0
  31. package/dist-client/label-studio-project-create.js.map +1 -0
  32. package/dist-client/label-studio-project-list.d.ts +16 -0
  33. package/dist-client/label-studio-project-list.js +222 -0
  34. package/dist-client/label-studio-project-list.js.map +1 -0
  35. package/dist-client/label-studio-wrapper.d.ts +57 -0
  36. package/dist-client/label-studio-wrapper.js +304 -0
  37. package/dist-client/label-studio-wrapper.js.map +1 -0
  38. package/dist-client/route.d.ts +1 -0
  39. package/dist-client/route.js +14 -0
  40. package/dist-client/route.js.map +1 -0
  41. package/dist-client/tsconfig.tsbuildinfo +1 -0
  42. package/dist-server/controller/label-studio-role-mapper.d.ts +35 -0
  43. package/dist-server/controller/label-studio-role-mapper.js +65 -0
  44. package/dist-server/controller/label-studio-role-mapper.js.map +1 -0
  45. package/dist-server/controller/user-provisioning-service.d.ts +66 -0
  46. package/dist-server/controller/user-provisioning-service.js +264 -0
  47. package/dist-server/controller/user-provisioning-service.js.map +1 -0
  48. package/dist-server/index.d.ts +7 -0
  49. package/dist-server/index.js +19 -0
  50. package/dist-server/index.js.map +1 -0
  51. package/dist-server/route/label-studio-sso.d.ts +2 -0
  52. package/dist-server/route/label-studio-sso.js +156 -0
  53. package/dist-server/route/label-studio-sso.js.map +1 -0
  54. package/dist-server/route/webhook.d.ts +65 -0
  55. package/dist-server/route/webhook.js +248 -0
  56. package/dist-server/route/webhook.js.map +1 -0
  57. package/dist-server/route.d.ts +1 -0
  58. package/dist-server/route.js +21 -0
  59. package/dist-server/route.js.map +1 -0
  60. package/dist-server/service/ai-prediction-service.d.ts +27 -0
  61. package/dist-server/service/ai-prediction-service.js +222 -0
  62. package/dist-server/service/ai-prediction-service.js.map +1 -0
  63. package/dist-server/service/dataset-labeling-integration.d.ts +44 -0
  64. package/dist-server/service/dataset-labeling-integration.js +512 -0
  65. package/dist-server/service/dataset-labeling-integration.js.map +1 -0
  66. package/dist-server/service/external-data-source-service.d.ts +78 -0
  67. package/dist-server/service/external-data-source-service.js +415 -0
  68. package/dist-server/service/external-data-source-service.js.map +1 -0
  69. package/dist-server/service/index.d.ts +12 -0
  70. package/dist-server/service/index.js +27 -0
  71. package/dist-server/service/index.js.map +1 -0
  72. package/dist-server/service/label-studio-sso-service.d.ts +38 -0
  73. package/dist-server/service/label-studio-sso-service.js +98 -0
  74. package/dist-server/service/label-studio-sso-service.js.map +1 -0
  75. package/dist-server/service/ml/ml-backend-service.d.ts +23 -0
  76. package/dist-server/service/ml/ml-backend-service.js +153 -0
  77. package/dist-server/service/ml/ml-backend-service.js.map +1 -0
  78. package/dist-server/service/prediction/prediction-management.d.ts +32 -0
  79. package/dist-server/service/prediction/prediction-management.js +299 -0
  80. package/dist-server/service/prediction/prediction-management.js.map +1 -0
  81. package/dist-server/service/project/project-management.d.ts +36 -0
  82. package/dist-server/service/project/project-management.js +309 -0
  83. package/dist-server/service/project/project-management.js.map +1 -0
  84. package/dist-server/service/task/task-management.d.ts +42 -0
  85. package/dist-server/service/task/task-management.js +372 -0
  86. package/dist-server/service/task/task-management.js.map +1 -0
  87. package/dist-server/service/user-provisioning/user-sync-mutation.d.ts +28 -0
  88. package/dist-server/service/user-provisioning/user-sync-mutation.js +111 -0
  89. package/dist-server/service/user-provisioning/user-sync-mutation.js.map +1 -0
  90. package/dist-server/service/webhook/webhook-management.d.ts +21 -0
  91. package/dist-server/service/webhook/webhook-management.js +134 -0
  92. package/dist-server/service/webhook/webhook-management.js.map +1 -0
  93. package/dist-server/tsconfig.tsbuildinfo +1 -0
  94. package/dist-server/types/dataset-labeling-types.d.ts +71 -0
  95. package/dist-server/types/dataset-labeling-types.js +259 -0
  96. package/dist-server/types/dataset-labeling-types.js.map +1 -0
  97. package/dist-server/types/label-studio-types.d.ts +128 -0
  98. package/dist-server/types/label-studio-types.js +494 -0
  99. package/dist-server/types/label-studio-types.js.map +1 -0
  100. package/dist-server/types/prediction-types.d.ts +39 -0
  101. package/dist-server/types/prediction-types.js +121 -0
  102. package/dist-server/types/prediction-types.js.map +1 -0
  103. package/dist-server/utils/annotation-exporter.d.ts +104 -0
  104. package/dist-server/utils/annotation-exporter.js +261 -0
  105. package/dist-server/utils/annotation-exporter.js.map +1 -0
  106. package/dist-server/utils/label-config-builder.d.ts +117 -0
  107. package/dist-server/utils/label-config-builder.js +286 -0
  108. package/dist-server/utils/label-config-builder.js.map +1 -0
  109. package/dist-server/utils/label-studio-api-client.d.ts +180 -0
  110. package/dist-server/utils/label-studio-api-client.js +401 -0
  111. package/dist-server/utils/label-studio-api-client.js.map +1 -0
  112. package/dist-server/utils/media-url-extractor.d.ts +45 -0
  113. package/dist-server/utils/media-url-extractor.js +152 -0
  114. package/dist-server/utils/media-url-extractor.js.map +1 -0
  115. package/dist-server/utils/task-transformer.d.ts +108 -0
  116. package/dist-server/utils/task-transformer.js +260 -0
  117. package/dist-server/utils/task-transformer.js.map +1 -0
  118. package/package.json +47 -0
  119. package/server/SERVER_STRUCTURE.md +351 -0
  120. package/server/controller/label-studio-role-mapper.ts +76 -0
  121. package/server/controller/user-provisioning-service.ts +340 -0
  122. package/server/index.ts +19 -0
  123. package/server/route/label-studio-sso.ts +194 -0
  124. package/server/route/webhook.ts +304 -0
  125. package/server/route.ts +35 -0
  126. package/server/service/ai-prediction-service.ts +239 -0
  127. package/server/service/dataset-labeling-integration.ts +590 -0
  128. package/server/service/external-data-source-service.ts +438 -0
  129. package/server/service/index.ts +24 -0
  130. package/server/service/label-studio-sso-service.ts +108 -0
  131. package/server/service/labeling-scenario-service.ts.deprecated +566 -0
  132. package/server/service/ml/ml-backend-service.ts +127 -0
  133. package/server/service/prediction/prediction-management.ts +281 -0
  134. package/server/service/project/project-management.ts +284 -0
  135. package/server/service/task/task-management.ts +363 -0
  136. package/server/service/user-provisioning/user-sync-mutation.ts +80 -0
  137. package/server/service/webhook/webhook-management.ts +109 -0
  138. package/server/tsconfig.json +11 -0
  139. package/server/types/dataset-labeling-types.ts +181 -0
  140. package/server/types/global.d.ts +23 -0
  141. package/server/types/label-studio-types.ts +346 -0
  142. package/server/types/prediction-types.ts +86 -0
  143. package/server/types/scenario-types.ts.deprecated +362 -0
  144. package/server/utils/annotation-exporter.ts +340 -0
  145. package/server/utils/label-config-builder.ts +340 -0
  146. package/server/utils/label-studio-api-client.ts +487 -0
  147. package/server/utils/media-url-extractor.ts +193 -0
  148. package/server/utils/task-transformer.ts +342 -0
  149. package/test-ai-prediction.js +268 -0
  150. package/test-dataset-integration.js +449 -0
  151. package/test-simple.js +89 -0
  152. package/things-factory.config.js +12 -0
package/SETUP_GUIDE.md ADDED
@@ -0,0 +1,577 @@
1
+ # Things-Factory & Label Studio Custom 통합 설정 가이드
2
+
3
+ Things-Factory에서 Label Studio Custom (SSO Edition)을 iframe으로 통합하고 SSO를 사용하는 완전한 설정 가이드입니다.
4
+
5
+ ---
6
+
7
+ ## 📋 사전 요구사항
8
+
9
+ - Things-Factory 서버 (9.1.0+)
10
+ - Label Studio Custom Docker 이미지: `ghcr.io/aidoop/label-studio-custom:1.20.0-sso.38`
11
+ - Docker & Docker Compose 설치
12
+ - PostgreSQL 13+ (Docker로 실행 가능)
13
+ - 관리자 권한
14
+ - HTTPS 사용 권장 (프로덕션 필수)
15
+
16
+ ---
17
+
18
+ ## 🐳 0단계: Label Studio Custom Docker 설치
19
+
20
+ ### Docker Compose로 빠른 설치
21
+
22
+ ```bash
23
+ # 1. 프로젝트 디렉토리 생성
24
+ mkdir label-studio-deployment
25
+ cd label-studio-deployment
26
+
27
+ # 2. docker-compose.yml 작성
28
+ cat > docker-compose.yml << 'EOF'
29
+ version: "3.8"
30
+
31
+ services:
32
+ postgres:
33
+ image: postgres:13.18
34
+ container_name: label-studio-postgres
35
+ restart: unless-stopped
36
+
37
+ environment:
38
+ POSTGRES_DB: labelstudio
39
+ POSTGRES_USER: postgres
40
+ POSTGRES_PASSWORD: dev_postgres_2024
41
+ PGDATA: /var/lib/postgresql/data/pgdata
42
+
43
+ volumes:
44
+ - postgres_data:/var/lib/postgresql/data
45
+
46
+ ports:
47
+ - "5432:5432"
48
+
49
+ networks:
50
+ - labelstudio
51
+
52
+ labelstudio:
53
+ image: ghcr.io/aidoop/label-studio-custom:1.20.0-sso.38
54
+ container_name: label-studio-app
55
+ restart: unless-stopped
56
+
57
+ depends_on:
58
+ - postgres
59
+
60
+ environment:
61
+ # Database
62
+ DJANGO_DB: default
63
+ POSTGRES_HOST: postgres
64
+ POSTGRES_PORT: 5432
65
+ POSTGRES_DB: labelstudio
66
+ POSTGRES_USER: postgres
67
+ POSTGRES_PASSWORD: dev_postgres_2024
68
+
69
+ # Django
70
+ DEBUG: false
71
+ LOG_LEVEL: INFO
72
+
73
+ # SSO Configuration
74
+ JWT_SSO_NATIVE_USER_ID_CLAIM: user_id
75
+ JWT_SSO_COOKIE_NAME: ls_auth_token
76
+ JWT_SSO_TOKEN_PARAM: token
77
+ SSO_TOKEN_EXPIRY: 600
78
+
79
+ # Label Studio
80
+ LABEL_STUDIO_HOST: http://label.hatiolab.localhost:8080
81
+
82
+ # Cookie Settings (서브도메인 공유)
83
+ SESSION_COOKIE_DOMAIN: .hatiolab.localhost
84
+ CSRF_COOKIE_DOMAIN: .hatiolab.localhost
85
+
86
+ # iframe Security Headers
87
+ CSP_FRAME_ANCESTORS: "'self' http://localhost:3000 http://hatiolab.localhost:3000"
88
+
89
+ # Other
90
+ FEATURE_FLAGS_OFFLINE: true
91
+ STORAGE_PERSISTENCE: true
92
+
93
+ volumes:
94
+ - labelstudio_data:/label-studio/data
95
+
96
+ ports:
97
+ - "8080:8080"
98
+
99
+ healthcheck:
100
+ test: ["CMD", "curl", "-f", "http://localhost:8080/health"]
101
+ interval: 30s
102
+ timeout: 10s
103
+ retries: 3
104
+ start_period: 60s
105
+
106
+ networks:
107
+ - labelstudio
108
+
109
+ volumes:
110
+ postgres_data:
111
+ driver: local
112
+
113
+ labelstudio_data:
114
+ driver: local
115
+
116
+ networks:
117
+ labelstudio:
118
+ driver: bridge
119
+ EOF
120
+
121
+ # 3. 실행
122
+ docker compose up -d
123
+
124
+ # 4. 로그 확인
125
+ docker compose logs -f labelstudio
126
+
127
+ # 5. Admin 사용자 생성 (최초 1회)
128
+ docker compose exec labelstudio python manage.py createsuperuser
129
+ # → Email: admin@hatiolab.io
130
+ # → Username: admin
131
+ # → Password: admin (또는 원하는 패스워드)
132
+
133
+ # 6. API 토큰 발급
134
+ # http://label.hatiolab.localhost:8080 접속
135
+ # Account Settings → Access Token → Create new token
136
+ # 생성된 토큰을 복사 (예: 2c00d45b8318a11f59e04c7233d729f3f17664e8)
137
+
138
+ # 7. .env 파일에 API 토큰 추가 (선택사항)
139
+ cat > .env << 'EOF'
140
+ LABEL_STUDIO_API_TOKEN=2c00d45b8318a11f59e04c7233d729f3f17664e8
141
+ EOF
142
+ ```
143
+
144
+ ### 접속 확인
145
+
146
+ - **Label Studio**: http://label.hatiolab.localhost:8080
147
+ - **Health Check**: http://label.hatiolab.localhost:8080/health
148
+ - **PostgreSQL**: localhost:5432
149
+
150
+ ---
151
+
152
+ ## 🔧 1단계: Things-Factory 설정
153
+
154
+ ### 1.1 모듈 빌드
155
+
156
+ ```bash
157
+ # Things-Factory 프로젝트 디렉토리로 이동
158
+ cd /path/to/things-factory
159
+
160
+ # integration-label-studio 모듈 빌드
161
+ cd packages/integration-label-studio
162
+ yarn build
163
+
164
+ # 루트로 돌아가기
165
+ cd ../..
166
+ ```
167
+
168
+ ### 1.2 설정 파일 작성
169
+
170
+ `config/label-studio.config.js` 파일 생성:
171
+
172
+ ```javascript
173
+ module.exports = {
174
+ labelStudio: {
175
+ serverUrl: process.env.LABEL_STUDIO_URL || 'http://localhost:8080',
176
+ apiToken: process.env.LABEL_STUDIO_API_TOKEN || '',
177
+ interfaces: 'panel,controls,annotations:menu' // 표시할 UI 요소
178
+ }
179
+ }
180
+ ```
181
+
182
+ ### 1.3 환경 변수 설정
183
+
184
+ `.env` 파일에 추가:
185
+
186
+ ```bash
187
+ # Label Studio 서버 URL
188
+ LABEL_STUDIO_URL=https://label-studio.example.com
189
+
190
+ # Label Studio API 토큰 (사용자 동기화용)
191
+ LABEL_STUDIO_API_TOKEN=your-api-token-here
192
+ ```
193
+
194
+ ### 1.4 Things-Factory 재시작
195
+
196
+ ```bash
197
+ cd /path/to/things-factory
198
+ yarn workspace @things-factory/[APP_NAME] run serve:dev
199
+ # 또는 프로덕션
200
+ yarn workspace @things-factory/[APP_NAME] run serve
201
+ ```
202
+
203
+ ---
204
+
205
+ ## 📦 2단계: Label Studio SSO 패키지 설치
206
+
207
+ ### 2.1 label-studio-sso 패키지 설치
208
+
209
+ ```bash
210
+ # Label Studio 가상환경 활성화
211
+ source /path/to/label-studio/venv/bin/activate
212
+
213
+ # 패키지 설치
214
+ pip install label-studio-sso
215
+
216
+ # 설치 확인
217
+ pip list | grep label-studio-sso
218
+ ```
219
+
220
+ ### 2.2 Label Studio 설정 수정
221
+
222
+ `label_studio/core/settings/base.py` 파일 수정:
223
+
224
+ ```python
225
+ # INSTALLED_APPS에 추가
226
+ INSTALLED_APPS = [
227
+ 'django.contrib.admin',
228
+ 'django.contrib.auth',
229
+ 'django.contrib.contenttypes',
230
+ 'django.contrib.sessions',
231
+ 'django.contrib.messages',
232
+ 'django.contrib.staticfiles',
233
+
234
+ # ... 기존 앱들 ...
235
+
236
+ 'label_studio_sso', # ✅ 추가
237
+ ]
238
+
239
+ # AUTHENTICATION_BACKENDS에 추가 (최상단에 배치)
240
+ AUTHENTICATION_BACKENDS = [
241
+ 'label_studio_sso.backends.JWTAuthenticationBackend', # ✅ 추가 (최우선)
242
+ 'rules.permissions.ObjectPermissionBackend',
243
+ 'django.contrib.auth.backends.ModelBackend',
244
+ ]
245
+
246
+ # MIDDLEWARE에 추가 (AuthenticationMiddleware 바로 다음)
247
+ MIDDLEWARE = [
248
+ 'corsheaders.middleware.CorsMiddleware',
249
+ 'django.middleware.security.SecurityMiddleware',
250
+ 'django.contrib.sessions.middleware.SessionMiddleware',
251
+ 'django.middleware.locale.LocaleMiddleware',
252
+ 'core.middleware.DisableCSRF',
253
+ 'django.middleware.csrf.CsrfViewMiddleware',
254
+ 'core.middleware.XApiKeySupportMiddleware',
255
+ 'django.contrib.auth.middleware.AuthenticationMiddleware',
256
+ 'label_studio_sso.middleware.JWTAutoLoginMiddleware', # ✅ 추가
257
+ 'django.contrib.messages.middleware.MessageMiddleware',
258
+ 'django.middleware.clickjacking.XFrameOptionsMiddleware',
259
+ # ... 나머지 미들웨어 ...
260
+ ]
261
+
262
+ # JWT SSO 설정
263
+ JWT_SSO_SECRET = os.getenv('JWT_SSO_SECRET')
264
+ JWT_SSO_ALGORITHM = 'HS256'
265
+ JWT_SSO_TOKEN_PARAM = 'token'
266
+ JWT_SSO_EMAIL_CLAIM = 'email'
267
+ JWT_SSO_AUTO_CREATE_USERS = False # Things-Factory 사용자 동기화 사용
268
+ ```
269
+
270
+ ### 2.3 Label Studio 재시작
271
+
272
+ ```bash
273
+ # systemd 사용 시
274
+ sudo systemctl restart label-studio
275
+
276
+ # 수동 실행 시
277
+ python label_studio/manage.py runserver 0.0.0.0:8080
278
+ ```
279
+
280
+ ---
281
+
282
+ ## 👥 3단계: Label Studio API 토큰 생성
283
+
284
+ ### 3.1 Label Studio에서 API 토큰 생성
285
+
286
+ 1. Label Studio에 로그인
287
+ 2. **Account Settings** → **Access Token** 메뉴 이동
288
+ 3. **"Create new token"** 클릭
289
+ 4. 생성된 토큰 복사 (예: `a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6`)
290
+
291
+ ### 3.2 Things-Factory 환경 변수에 추가
292
+
293
+ `.env` 파일의 `LABEL_STUDIO_API_TOKEN`에 복사한 토큰 추가:
294
+
295
+ ```bash
296
+ LABEL_STUDIO_API_TOKEN=a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6
297
+ ```
298
+
299
+ ---
300
+
301
+ ## 👥 4단계: 사용자 권한 설정 및 동기화
302
+
303
+ ### 4.1 Label Studio 권한 부여
304
+
305
+ Things-Factory에서 사용자에게 `label-studio` 권한을 부여합니다.
306
+
307
+ **Things-Factory Admin UI**:
308
+
309
+ 1. Users 메뉴 → 사용자 선택
310
+ 2. "Granted Roles" 탭
311
+ 3. `label-studio` 권한이 포함된 역할 추가
312
+
313
+ ### 4.2 사용자 동기화
314
+
315
+ Things-Factory GraphQL Playground에서 사용자를 Label Studio로 동기화:
316
+
317
+ **전체 사용자 동기화 (관리자용)**:
318
+
319
+ ```graphql
320
+ mutation {
321
+ syncAllUsersToLabelStudio {
322
+ total
323
+ created
324
+ updated
325
+ deactivated
326
+ skipped
327
+ errors
328
+ results {
329
+ success
330
+ email
331
+ action
332
+ lsUserId
333
+ lsPermissions
334
+ error
335
+ }
336
+ }
337
+ }
338
+ ```
339
+
340
+ **현재 사용자만 동기화**:
341
+
342
+ ```graphql
343
+ mutation {
344
+ syncMyUserToLabelStudio {
345
+ success
346
+ email
347
+ action
348
+ lsUserId
349
+ lsPermissions
350
+ error
351
+ }
352
+ }
353
+ ```
354
+
355
+ **예상 출력**:
356
+
357
+ ```json
358
+ {
359
+ "data": {
360
+ "syncAllUsersToLabelStudio": {
361
+ "total": 10,
362
+ "created": 5,
363
+ "updated": 3,
364
+ "deactivated": 2,
365
+ "skipped": 0,
366
+ "errors": 0,
367
+ "results": [
368
+ {
369
+ "success": true,
370
+ "email": "user@example.com",
371
+ "action": "created",
372
+ "lsUserId": "123",
373
+ "lsPermissions": "Staff (Labeling only)",
374
+ "error": null
375
+ }
376
+ ]
377
+ }
378
+ }
379
+ }
380
+ ```
381
+
382
+ ---
383
+
384
+ ## ✅ 5단계: 통합 검증
385
+
386
+ ### 5.1 Things-Factory에서 접근
387
+
388
+ 1. Things-Factory 로그인
389
+ 2. 메뉴에서 **"Label Studio"** 클릭
390
+ 3. iframe에 Label Studio가 로드되어야 함
391
+ 4. **자동으로 로그인되어야 함** (별도 로그인 없이)
392
+
393
+ ### 5.2 JWT 토큰 확인
394
+
395
+ **브라우저 개발자 도구**에서 iframe URL 확인:
396
+
397
+ ```
398
+ https://label-studio.example.com/?token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...&interfaces=panel,controls,annotations:menu
399
+ ```
400
+
401
+ **localStorage에서 토큰 확인**:
402
+
403
+ ```javascript
404
+ // 브라우저 콘솔에서
405
+ localStorage.getItem('access-token')
406
+ ```
407
+
408
+ ### 5.3 Label Studio 로그 확인
409
+
410
+ ```bash
411
+ tail -f /var/log/label-studio/label-studio.log | grep "JWT"
412
+ ```
413
+
414
+ **성공 메시지**:
415
+
416
+ ```
417
+ INFO: JWT token verified for email: user@example.com
418
+ INFO: User found: user@example.com
419
+ INFO: User auto-logged in: user@example.com
420
+ ```
421
+
422
+ **실패 메시지**:
423
+
424
+ ```
425
+ ERROR: JWT_SSO_SECRET is not configured
426
+ ERROR: JWT token signature verification failed
427
+ WARNING: User not found in Label Studio: user@example.com
428
+ ```
429
+
430
+ ---
431
+
432
+ ## 🔍 문제 해결
433
+
434
+ ### 문제 1: "JWT token signature verification failed"
435
+
436
+ **원인**: Things-Factory와 Label Studio의 `JWT_SSO_SECRET`이 다름
437
+
438
+ **해결**:
439
+
440
+ ```bash
441
+ # 1. Things-Factory 시크릿 확인
442
+ cd /path/to/things-factory
443
+ cat .env | grep JWT_SSO_SECRET
444
+
445
+ # 2. Label Studio 시크릿 확인
446
+ echo $JWT_SSO_SECRET
447
+
448
+ # 3. 두 값이 동일한지 확인
449
+ # 다르면 둘 중 하나를 수정하고 양쪽 모두 재시작
450
+ ```
451
+
452
+ ### 문제 2: iframe에 "Refused to connect" 에러
453
+
454
+ **원인**: Label Studio의 X-Frame-Options 설정
455
+
456
+ **해결**:
457
+
458
+ ```python
459
+ # Label Studio settings.py
460
+ X_FRAME_OPTIONS = 'ALLOWALL' # 또는 특정 도메인 허용
461
+ ```
462
+
463
+ ### 문제 3: 사용자가 Label Studio에 없음
464
+
465
+ **원인**: 사용자 동기화가 안됨
466
+
467
+ **해결**:
468
+
469
+ ```graphql
470
+ # Things-Factory GraphQL
471
+ mutation {
472
+ syncMyUserToLabelStudio {
473
+ success
474
+ email
475
+ action
476
+ lsUserId
477
+ error
478
+ }
479
+ }
480
+ ```
481
+
482
+ 또는 Label Studio에서 수동 생성:
483
+
484
+ ```bash
485
+ cd /path/to/label-studio
486
+ python manage.py createsuperuser --email user@example.com
487
+ ```
488
+
489
+ ### 문제 4: HTTPS에서만 작동
490
+
491
+ **원인**: JWT 토큰이 URL에 포함되므로 보안상 HTTPS 필요
492
+
493
+ **해결**:
494
+
495
+ - 개발: `http://localhost` 사용 (로컬호스트는 예외)
496
+ - 프로덕션: 반드시 HTTPS 사용
497
+
498
+ ---
499
+
500
+ ## 📊 설정 확인 체크리스트
501
+
502
+ ### Things-Factory
503
+
504
+ ```bash
505
+ # 1. 환경 변수 확인
506
+ cat .env | grep LABEL_STUDIO
507
+
508
+ # 2. 모듈 빌드 확인
509
+ ls -la packages/integration-label-studio/dist-server/
510
+ ls -la packages/integration-label-studio/dist-client/
511
+
512
+ # 3. 설정 파일 확인
513
+ cat config/label-studio.config.js
514
+
515
+ # 4. 서버 재시작
516
+ yarn workspace @things-factory/[APP_NAME] run serve:dev
517
+ ```
518
+
519
+ ### Label Studio
520
+
521
+ ```bash
522
+ # 1. 패키지 설치 확인
523
+ pip list | grep label-studio-sso
524
+
525
+ # 2. 환경 변수 확인
526
+ echo $JWT_SSO_SECRET
527
+
528
+ # 3. 설정 파일 확인
529
+ grep -A 5 "label_studio_sso" label_studio/core/settings/base.py
530
+
531
+ # 4. 서버 재시작
532
+ sudo systemctl restart label-studio
533
+ ```
534
+
535
+ ---
536
+
537
+ ## 🔐 보안 고려사항
538
+
539
+ ### 1. JWT 시크릿 보안
540
+
541
+ - **절대 Git에 커밋하지 마세요**
542
+ - `.gitignore`에 `.env` 추가
543
+ - 프로덕션에서는 환경 변수 또는 비밀 관리 도구 사용
544
+
545
+ ### 2. HTTPS 필수
546
+
547
+ - 프로덕션에서는 반드시 HTTPS 사용
548
+ - JWT 토큰이 URL에 포함되므로 중간자 공격 방지 필요
549
+
550
+ ### 3. 토큰 유효 기간
551
+
552
+ - Things-Factory JWT 토큰 유효 기간: 5-10분 권장
553
+ - 만료 후 재로그인 필요
554
+
555
+ ### 4. CORS 설정
556
+
557
+ ```python
558
+ # Label Studio settings.py
559
+ CORS_ALLOWED_ORIGINS = [
560
+ 'https://things-factory.example.com',
561
+ ]
562
+ ```
563
+
564
+ ---
565
+
566
+ ## 📚 추가 문서
567
+
568
+ - [README.md](./README.md) - 모듈 개요
569
+ - [USER_SYNC_GUIDE.md](./USER_SYNC_GUIDE.md) - 사용자 동기화 가이드
570
+ - [label-studio-sso README](https://github.com/hatiolab/label-studio-sso) - SSO 패키지 문서
571
+ - [label-studio-sso CONFIGURATION](https://github.com/hatiolab/label-studio-sso/blob/main/CONFIGURATION.md) - 상세 설정
572
+
573
+ ---
574
+
575
+ **문서 버전**: 1.0
576
+ **작성일**: 2025-10-02
577
+ **최종 업데이트**: 2025-10-02