Estado
El estado del paquete es Implementado y verificado localmente. La suite de pruebas unitarias de JVM se ejecuta correctamente y cubre PKCE, la gestión del estado y el nonce, la capacidad de invitado y los contratos de almacenamiento. EncryptedSharedPreferences, Chrome Custom Tabs, App Links y un recorrido de ida y vuelta con un IdP real aún requieren un dispositivo o emulador. Esta página documenta el comportamiento implementado; no afirma que esté listo para producción.
Estado del registro: UNPUBLISHED. Instala este SDK únicamente desde el checkout del código fuente del repositorio; no uses un registro de paquetes externo.
Requisitos
- Android API 26+ (Android 8.0)
- Kotlin 1.9+ y AndroidX
Instalación
Añade la dependencia al build.gradle.kts del módulo de tu app:
// settings.gradle.kts
includeBuild("../xid/sdk/android")
// app/build.gradle.kts
dependencies {
implementation("dev.xid:xid-android:0.1.0-alpha.0")
}Configuración del manifiesto
Registra una Activity de callback con un intent-filter. Se recomiendan los App Links (esquema HTTPS con autoVerify) sobre los esquemas personalizados:
<!-- 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>Inicio rápido
import dev.xid.sdk.Xid
import dev.xid.sdk.model.XidConfig
// 1. Initialize in Application.onCreate. offline_access is rejected until DPoP is implemented.
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"),
)
)
// 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. Read the current unexpired session. Expiry requires reauthorization.
val session = Xid.getSession()
// 5. Get the current unexpired access token.
val token = Xid.getAccessToken()
// 6. Clear local state and optionally open end_session.
Xid.signOut(context = this, openEndSession = true)API principal
| Método | Firma |
|---|---|
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 error
Todos los errores del SDK son subtipos de la clase sellada XidException:
| Subclase | Disparador |
|---|---|
NotConfigured |
configure() no fue llamado |
UserCancelled |
El usuario cerró Custom Tabs sin completar el flujo |
StateMismatch |
Desfase en el estado OAuth: posible CSRF |
TokenExchangeFailed |
El endpoint de tokens devolvió un error |
TokenValidationFailed |
Falló la validación de la firma o las claims del token de ID |
NoSession |
Método de sesión llamado sin sesión iniciada |
Seguridad
- Cliente público: no se almacena ni transmite ningún secreto de cliente.
- Solo PKCE S256. El servidor rechaza el método plain de challenge.
- EncryptedSharedPreferences respaldado por Android Keystore (AES-256-GCM) protege el almacén de tokens en reposo.
- Estado OAuth aleatorio generado por solicitud; validado en la redirección para prevenir CSRF.
Limitaciones conocidas
- La verificación de ID token basada en JWKS está implementada y probada localmente. Las pruebas con dispositivo o emulador Android e IdP real siguen siendo necesarias para L4.
- No hay mecanismo para detectar cuándo el usuario cierra Custom Tabs sin completar la autorización.
- Solo una cuenta: la capa de almacenamiento usa claves fijas.