Ir para o conteúdo

sdk/android

SDK Kotlin para Android usando Chrome Custom Tabs, fluxo de código deautorização PKCE S256 e armazenamento de tokens comEncryptedSharedPreferences baseado em Keystore.

Ver como Markdown

Estado

O status do pacote é Implementado · verificado localmente.Testes unitários JVM (24 passaram) cobrem geração de PKCE, stateOAuth e armazenamento em memória. EncryptedSharedPreferences(Keystore AES-256-GCM), Chrome Custom Tabs e o comportamento de AppLinks requerem um dispositivo ou emulador Android real. A ida e voltareal com o IdP está pendente de verificação manual. Esta páginadocumenta o comportamento implementado; não é uma declaração deprontidão para produção.

Requisitos

  • Android API 26+ (Android 8.0)
  • Kotlin 1.9+ e AndroidX

Instalação

Adicione a dependência ao build.gradle.kts do módulo do seuaplicativo:

dependencies {
    implementation("dev.xid:xid-android:0.1.0-alpha")
}

// Local development: add to settings.gradle.kts
includeBuild("../sdk/android")

Configuração do manifesto

Registre uma Activity de callback com um intent-filter. App Links(esquema HTTPS com autoVerify) são recomendados em vez de esquemaspersonalizados:

<!-- AndroidManifest.xml -->
<activity android:name=".AuthCallbackActivity" android:exported="true">
    <intent-filter android:autoVerify="true">
        <action android:name="android.intent.action.VIEW" />
        <category android:name="android.intent.category.DEFAULT" />
        <category android:name="android.intent.category.BROWSABLE" />
        <data android:scheme="https"
              android:host="yourapp.example.com"
              android:pathPrefix="/auth/callback" />
    </intent-filter>
</activity>

Início rápido

import dev.xid.sdk.Xid
import dev.xid.sdk.model.XidConfig

// 1. Initialize in Application.onCreate
Xid.configure(
    context = this,
    config = XidConfig(
        issuer = "https://xid.dev",
        clientId = "your_client_id",
        redirectUri = "https://yourapp.example.com/auth/callback",
        scopes = listOf("openid", "profile", "email", "offline_access"),
    )
)

// 2. Sign in (opens Chrome Custom Tabs)
lifecycleScope.launch { Xid.signIn(requireContext()) }

// 3. Handle redirect in AuthCallbackActivity
val session = Xid.handleRedirect(intent.data.toString())

// 4. Get current session (auto-refreshes near expiry)
val session = Xid.getSession()

// 5. Get access token
val token = Xid.getAccessToken()

// 6. Sign out
Xid.signOut(context = this, openEndSession = true)

API principal

Método Assinatura
configure fun configure(context: Context, config: XidConfig)
signIn suspend fun signIn(context: Context, options: SignInOptions? = null)
handleRedirect suspend fun handleRedirect(url: String): XidSession
getSession suspend fun getSession(): XidSession?
getAccessToken suspend fun getAccessToken(options: GetAccessTokenOptions? = null): String
signOut suspend fun signOut(context: Context? = null, openEndSession: Boolean = false)
setTokenStorage fun setTokenStorage(adapter: TokenStorageAdapter)

Tipos de erro

Todos os erros do SDK são subtipos da sealed class XidException:

Subclasse Gatilho
NotConfigured configure() não foi chamado
UserCancelled O usuário fechou as Custom Tabs sem concluir
StateMismatch Divergência de state OAuth — possível CSRF
TokenExchangeFailed O endpoint de token retornou um erro
TokenRefreshFailed Refresh token expirado ou revogado
NoSession Método de sessão chamado enquanto desconectado

Segurança

  • Cliente público — nenhum segredo de cliente armazenado ou transmitido.
  • Apenas PKCE S256. O servidor rejeita o método de desafio plain.
  • EncryptedSharedPreferences baseado em Android Keystore (AES-256-GCM)protege o armazenamento de tokens em repouso.
  • State OAuth aleatório gerado por requisição; validado noredirecionamento para prevenir CSRF.

Limitações conhecidas

  • A verificacao de ID token com JWKS esta implementada e testada localmente. Testes com dispositivo ou emulador Android e IdP real ainda sao necessarios para L4.
  • Nenhum mecanismo para detectar quando o usuário fecha as Custom Tabssem concluir a autorização.
  • Apenas conta única — a camada de armazenamento usa chaves fixas.
Navegação

Digite para pesquisar...

Use as teclas de seta para navegarPressione Enter para selecionarPressione Escape para fechar