콘텐츠로 건너뛰기

sdk/flutter

flutter_web_auth_2, PKCE S256 인증 코드 흐름, flutter_secure_storage 토큰 영속성을 사용하는 iOS, Android, 데스크톱용 Dart / Flutter SDK.

Markdown으로 보기

상태

패키지 상태: 구현됨 · 로컬 검증 완료. 순수 Dart 단위 테스트(21개 통과)가 PKCE, 토큰 모델, 인메모리 저장소를 다룹니다. 플랫폼 채널 경로(flutter_secure_storage, flutter_web_auth_2)는 검증을 위해 실제 기기 또는 시뮬레이터가 필요합니다. 실제 IdP 왕복 테스트는 수동 검증 대기 중입니다. 이 페이지는 구현된 동작을 문서화하며, 프로덕션 준비 완료를 의미하지 않습니다.

설치

pubspec.yaml에 추가하고 flutter pub get을 실행하세요:

# pubspec.yaml
dependencies:
  xid:
    git:
      url: https://github.com/StringKe/xid
      path: sdk/flutter
      ref: main

플랫폼 설정

각 플랫폼에 콜백 URI 스킴을 등록하세요.

<!-- Android: AndroidManifest.xml (main Activity) -->
<intent-filter>
  <action android:name="android.intent.action.VIEW" />
  <category android:name="android.intent.category.DEFAULT" />
  <category android:name="android.intent.category.BROWSABLE" />
  <data android:scheme="com.example.myapp" android:host="auth" />
</intent-filter>

<!-- iOS: Info.plist -->
<key>CFBundleURLTypes</key>
<array>
  <dict>
    <key>CFBundleURLSchemes</key>
    <array><string>com.example.myapp</string></array>
  </dict>
</array>

빠른 시작

import 'package:xid/xid.dart';

final client = XidClient();

// 1. Initialize (fetches OIDC discovery)
await client.configure(
  const XidOptions(
    issuer: 'https://xid.dev',
    clientId: 'YOUR_CLIENT_ID',
    redirectUri: 'com.example.myapp://auth/callback',
    scopes: ['openid', 'profile', 'email', 'offline_access'],
  ),
);

// 2. Sign in (opens system browser, PKCE S256)
final session = await client.signIn();
print(session.user.email);

// 3. Get valid access token (auto-refreshes)
final token = await client.getAccessToken();

// 4. Get current session
final current = await client.getSession();

// 5. Sign out (revokes refresh token + clears secure storage)
await client.signOut();

핵심 API

방법 설명
configure(XidOptions, {storageAdapter?}) SDK를 초기화하고 OIDC 디스커버리를 가져옵니다. 다른 모든 메서드보다 먼저 호출해야 합니다.
signIn({}additionalParameters?, audience?}) PKCE S256 인증 URL로 시스템 브라우저를 엽니다. 코드를 교환하고 XidSession을 반환합니다.
handleRedirect(String url) App Link 또는 사용자 정의 스킴 콜백을 처리합니다. signIn 내부에서 호출됩니다. 크로스 프로세스 리디렉션 복구 시 수동으로 호출하세요.
getSession() XidSession?을 반환합니다. 액세스 토큰이 만료에 임박하면(60초 이내) refresh 토큰 교체를 트리거합니다.
getAccessToken({}bool forceRefresh}) 유효한 액세스 토큰 문자열을 반환합니다. forceRefresh: true를 전달하면 강제 갱신합니다.
signOut({}bool openLogoutUrl}) refresh 토큰을 폐기하고(RFC 7009) 안전 저장소를 지우며 선택적으로 브라우저에서 end_session_endpoint를 엽니다.
setTokenStorage(TokenStorageAdapter) 기본 SecureStorageAdapter(flutter_secure_storage)를 사용자 정의 구현으로 교체합니다.

의존성

패키지 버전 목적
flutter_web_auth_2 ^4.0.0 시스템 브라우저 인증 세션 및 콜백 수신
flutter_secure_storage ^9.2.4 플랫폼 안전 저장소(Keychain / Keystore / DPAPI)
crypto ^3.0.3 PKCE S256 challenge 계산을 위한 SHA-256
http ^1.2.2 discovery 및 token 엔드포인트용 HTTP 클라이언트

보안

  • 공개 클라이언트 — client secret이 저장되거나 전송되지 않습니다.
  • PKCE S256만 사용합니다. implicit 흐름과 password grant는 지원하지 않습니다.
  • 요청마다 생성되는 OAuth state; CSRF를 방지하기 위해 handleRedirect에서 검증됩니다.
  • Refresh 토큰은 플랫폼 안전 저장소(iOS의 Keychain, Android의 Keystore)에 저장되며 XID 서버에 의해 매번 사용 시 교체됩니다.

알려진 제한 사항

  • JWKS 기반 ES256 ID token 검증, state 기반 영속 PKCE, refresh single-flight는 구현되어 로컬 테스트를 통과했습니다. L4 지원 전에는 실제 기기와 IdP 검증이 필요합니다.
  • refresh 토큰을 받으려면 scopes에 offline_access가 포함되어야 합니다.
탐색

입력하여 검색...

화살표 키로 이동Enter 키로 선택Escape 키로 닫기