5.3 KiB
5.3 KiB
Baron SSO 권한 선택 및 동적 스코프(Scope) 처리 흐름
이 문서는 사용자가 Consent(권한 동의) 화면에서 특정 권한(Scope)을 선택하고, 그 선택된 권한들이 어떻게 백엔드와 Ory Hydra로 전달되어 처리되는지에 대한 구현 상세를 설명합니다. 또한, 개발자 포털(devfront)에서 설정한 권한별 설명이 어떻게 화면에 동적으로 표시되는지 설명합니다.
1. 개요
사용자 중심의 개인정보 제어를 위해 다음과 같은 기능이 구현되었습니다.
- 권한 선택: 사용자는 필수(Mandatory)가 아닌 권한을 직접 선택하거나 해제할 수 있습니다.
- 동적 설명: 개발자 포털에서 설정한 각 권한에 대한 사용자 친화적인 설명(한글 등)이 Consent 화면에 표시됩니다.
- 필수 권한 보장:
openid와 같이 서비스 동작에 필수적인 권한은 선택 해제가 불가능합니다.
2. 데이터 흐름 (Data Flow)
Step 1: Consent 정보 조회 (GET /consent)
사용자가 /consent 페이지에 진입하면, 프론트엔드는 백엔드에 상세 정보를 요청합니다.
- Frontend (
userfront):AuthProxyService.getConsentInfo(challenge)호출. - Backend (
backend):AuthHandler.GetConsentRequest핸들러 실행.- Hydra Admin API를 호출하여 Consent Request 정보(요청된 스코프, 클라이언트 정보 등)를 가져옵니다.
- 핵심 로직: Hydra Client의
Metadata필드 내structured_scopes를 파싱합니다. - 파싱된 정보를 바탕으로
scope_details객체(설명, 필수 여부 포함)를 생성하여 응답에 추가합니다.
// 백엔드 응답 예시
{
"challenge": "...",
"requested_scope": ["openid", "profile", "email"],
"scope_details": {
"openid": { "description": "인증 필수 정보", "mandatory": true },
"profile": { "description": "프로필 정보", "mandatory": false }
},
...
}
Step 2: UI 렌더링 및 사용자 선택
- Frontend (
userfront):ConsentScreen위젯 렌더링.- 백엔드에서 받은
requested_scope목록을 순회하며 체크박스를 생성합니다. scope_details에 있는 설명을 우선적으로 표시합니다.mandatory: true인 스코프(예:openid)는 체크박스를 비활성화(선택 고정)합니다.- 사용자는 나머지 선택 가능한 스코프를 체크하거나 해제합니다.
- 백엔드에서 받은
Step 3: 동의 처리 (POST /consent/accept)
사용자가 "동의하고 계속하기" 버튼을 클릭하면, 선택된 스코프 목록만 백엔드로 전송됩니다.
-
Frontend (
userfront):AuthProxyService.acceptConsent(challenge, grantScope: [...])호출.grant_scope파라미터에 사용자가 최종적으로 선택한 스코프 배열을 담아 보냅니다.
-
Backend (
backend):AuthHandler.AcceptConsentRequest핸들러 실행.- 요청 바디에서
grant_scope를 추출합니다. - 보안을 위해, 사용자가 보낸
grant_scope가 원래 요청된(requested) 스코프에 포함되는지 검증합니다. - 검증된 스코프 목록을 Hydra의
AcceptConsentRequest페이로드(grant_scope)에 담아 호출합니다.
- 요청 바디에서
-
Hydra:
- 전달받은
grant_scope만을 포함한 Access Token 및 ID Token을 생성할 준비를 하고, 최종 리다이렉트 URL을 반환합니다.
- 전달받은
3. 파일별 구현 상세
1. Backend (backend/internal/handler/auth_handler.go)
GetConsentRequest:- Hydra Client의 Metadata(
structured_scopes)를 읽어scope_details를 응답에 주입하는 로직이 추가되었습니다.
- Hydra Client의 Metadata(
AcceptConsentRequest:- 요청 바디 구조체에
GrantScope []string필드를 추가했습니다. - Hydra API 호출 시
RequestedScope필드를 사용자가 선택한 스코프로 덮어씌워 전달합니다.
- 요청 바디 구조체에
2. Frontend (userfront/lib/features/auth/presentation/consent_screen.dart)
_fetchConsentInfo:- API 응답의
scope_details를 파싱하여_scopeDescriptions와_mandatoryScopes상태를 동적으로 업데이트합니다.
- API 응답의
_acceptConsent:- 사용자가 체크한
_selectedScopes를 리스트로 변환하여 API 호출 시 전달합니다.
- 사용자가 체크한
- UI:
CheckboxListTile을 사용하여 각 권한별 선택 UI를 구성했습니다.
3. Frontend Service (userfront/lib/core/services/auth_proxy_service.dart)
acceptConsent:List<String>? grantScope파라미터를 추가하고, API 요청 바디에 포함시키는 기능을 구현했습니다.
4. 메타데이터 구조 (참고)
개발자 포털(devfront)에서 설정된 스코프 메타데이터는 Hydra Client의 metadata 필드에 다음과 같이 저장됩니다.
{
"metadata": {
"structured_scopes": [
{
"id": "1",
"name": "openid",
"description": "서비스 이용을 위한 필수 인증 정보입니다.",
"mandatory": true
},
{
"id": "2",
"name": "email",
"description": "이메일 알림을 받기 위해 필요합니다.",
"mandatory": false
}
]
}
}
백엔드는 이 정보를 읽어서 Consent 화면에 필요한 정보로 가공하여 전달합니다.