Untuk login dengan Auth0 di aplikasi Capacitor, buat sebuah Native aplikasi di Auth0, daftarkan URL callback custom-scheme seperti com.example.app://oauth/auth0, dan jalankan alur otorisasi code OpenID Connect dengan PKCE melalui browser sistem. Dengan @capgo/capacitor-social-login itu adalah satu initialize panggilan dengan endpoint Auth0 Anda dan satu SocialLogin.login({ provider: 'oauth2', options: { providerId: 'auth0' } }).
Panduan ini mencakup pengaturan dashboard Auth0, code klien untuk iOS, Android, dan web, API access token, refresh token, logout, dan error yang akan Anda temui. Ditulis untuk Capacitor 8 per Oktober 2026.
Cara kerja alur Auth0 di Capacitor
Auth0 menghosting halaman login (Universal Login). Aplikasi Anda tidak pernah melihat kata sandi. Alurnya adalah:
- Aplikasi menghasilkan PKCE verifier dan challenge, lalu membuka
https://YOUR_TENANT/authorizedi browser yang aman. - Pengguna masuk (password, sosial, passkey, MFA, apa pun yang Anda konfigurasikan di Auth0).
- Auth0 mengalihkan ke URL callback Anda dengan satu kali
code. - Aplikasi menukarkan code dan PKCE verifier di
/oauth/tokenuntuk mendapatkan ID token, access token, dan, jika diperlukan, refresh token.
Browser yang digunakan bergantung pada platform:
| Platform | Browser | Penanganan callback |
|---|---|---|
| iOS | ASWebAuthenticationSession |
Ditangani oleh sistem, tidak ada Info.plist ubah |
| Android | Embedded WebView secara default, atau Chrome Custom Tabs dengan androidUseCustomTabs: true |
Custom Tabs memerlukan intent filter |
| Web | Popup (default) atau redirect halaman penuh | handleRedirectCallback() di halaman kembali |
Di Android, gunakan Custom Tabs. Mereka berbagi cookie dengan Chrome, mendukung passkey dan password manager, serta mengikuti RFC 8252 (OAuth untuk aplikasi native), yang diharapkan oleh Auth0.
Langkah 1: Siapkan aplikasi Auth0
- Di Dashboard Auth0, buka Aplikasi > Aplikasi > Buat Aplikasi.
- Pilih Native dan buat aplikasinya.
- Pada tab Pengaturan tab, catat Domain (contohnya
example.eu.auth0.com) dan Client ID. - Di bawah Kredensial, pastikan metode autentikasi adalah Tidak ada. Itu adalah pengaturan public-client yang digunakan dengan PKCE.
Callback dan logout URLs
Isi kolom-kolom ini di Settings > Application URIs:
| Kolom | Nilai untuk mobile | Nilai untuk web |
|---|---|---|
| URL Callback yang Diizinkan | com.example.app://oauth/auth0 |
https://app.example.com/auth/callback |
| URL Logout yang Diizinkan | com.example.app://oauth/logout |
https://app.example.com/ |
| Origin Web yang Diizinkan | Tidak perlu | https://app.example.com |
Pisahkan beberapa nilai dengan koma. Gunakan Capacitor Anda appId sebagai scheme. Scheme reverse-domain menghindari bentrok dengan aplikasi lain. Jika Anda juga merilis build web, banyak tim membuat Single Page Application terpisah di Auth0, agar pengaturan web dan mobile tidak bercampur.
Refresh token
Jika pengguna harus tetap login:
- Di Pengaturan > Rotasi Token Refresh, aktifkan rotasi. Setiap refresh mengembalikan refresh token baru dan membatalkan yang lama.
- Atur masa berlaku absolut dan batas waktu inaktivitas yang sesuai dengan produk Anda.
- Jika Anda memanggil API Anda sendiri, buka Applications > APIs > API Anda > Settings dan aktifkan Izinkan Akses Offline.
- Minta
offline_accessscope di aplikasi.
audience API
Jika backend Anda memvalidasi access token Auth0, buatlah API di bawah Aplikasi > API dengan identifier seperti https://api.example.com. Teruskan identifier tersebut sebagai audience. Tanpa itu, access token hanya berlaku untuk /userinfo endpoint Auth0.
Langkah 2: Instal dan konfigurasi plugin
bun add @capgo/capacitor-social-login
bunx cap sync
Jika Auth0 adalah satu-satunya provider Anda, nonaktifkan SDK sosial bawaan agar binary tetap kecil:
// capacitor.config.ts
plugins: {
SocialLogin: {
providers: { google: false, facebook: false, apple: false, twitter: false },
},
},
Engine OAuth2 generik tidak bergantung pada SDK tersebut.
Android intent filter untuk Custom Tabs
Tambahkan callback scheme ke MainActivity di android/app/src/main/AndroidManifest.xml:
<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.app" android:host="oauth" />
</intent-filter>
Template Capacitor sudah mengatur android:launchMode="singleTask" aktif MainActivity, yang dibutuhkan oleh redirect. Biarkan tetap ada.
Langkah 3: Inisialisasi provider Auth0
import { Capacitor } from '@capacitor/core';
import { SocialLogin } from '@capgo/capacitor-social-login';
const AUTH0_DOMAIN = 'https://example.eu.auth0.com';
const isWeb = Capacitor.getPlatform() === 'web';
export async function initAuth() {
await SocialLogin.initialize({
oauth2: {
auth0: {
appId: 'YOUR_AUTH0_CLIENT_ID',
authorizationBaseUrl: `${AUTH0_DOMAIN}/authorize`,
accessTokenEndpoint: `${AUTH0_DOMAIN}/oauth/token`,
resourceUrl: `${AUTH0_DOMAIN}/userinfo`,
redirectUrl: isWeb
? 'https://app.example.com/auth/callback'
: 'com.example.app://oauth/auth0',
scope: 'openid profile email offline_access',
pkceEnabled: true,
additionalParameters: {
audience: 'https://api.example.com',
},
logoutUrl: `${AUTH0_DOMAIN}/oidc/logout`,
postLogoutRedirectUrl: isWeb
? 'https://app.example.com/'
: 'com.example.app://oauth/logout',
androidUseCustomTabs: true,
},
},
});
}
Anda dapat mengganti endpoint eksplisit dengan issuerUrl: AUTH0_DOMAIN. Plugin kemudian membaca /.well-known/openid-configuration. Nilai eksplisit mengungguli nilai yang terdeteksi, yang membantu saat Anda menggunakan domain kustom Auth0.
Jika Anda bermigrasi dari Ionic Auth Connect, plugin juga mengekspor SocialLoginAuthConnect dengan auth0 preset yang menerima domain, clientId, redirectUrl dan audience. Lihat Panduan migrasi Auth Connect.
Langkah 4: Masuk
import { SocialLogin } from '@capgo/capacitor-social-login';
export async function signInWithAuth0() {
try {
const { result } = await SocialLogin.login({
provider: 'oauth2',
options: { providerId: 'auth0' },
});
return {
idToken: result.idToken,
accessToken: result.accessToken?.token,
expiresAt: result.accessToken?.expires,
refreshToken: result.refreshToken,
user: result.resourceData, // JSON from /userinfo
};
} catch (error: any) {
if (error?.code === 'USER_CANCELLED') return null;
throw error;
}
}
Opsi login yang berguna:
prompt: 'login'memaksa halaman login meskipun Auth0 masih memiliki cookie sesi.loginHint: 'user@example.com'mengisi email secara otomatis.additionalParameters: { connection: 'google-oauth2' }melewati Universal Login dan langsung ke satu koneksi.additionalParameters: { screen_hint: 'signup' }membuka layar sign-up.
Callback redirect web
Di web, alur popup default tidak butuh tambahan apa pun. Jika Anda menggunakan flow: 'redirect', baca hasilnya di halaman callback:
const result = await SocialLogin.handleRedirectCallback();
if (result?.provider === 'oauth2') {
console.log(result.result.idToken);
}
handleRedirectCallback hanya untuk web dan ditolak di iOS dan Android.
Langkah 5: Baca ID token dan panggil API Anda
Decode ID token di client hanya untuk tampilan:
const { claims } = await SocialLogin.decodeIdToken({ idToken: result.idToken! });
console.log(claims.email, claims.name, claims.sub);
decodeIdToken tidak memeriksa signature. Untuk hal yang berkaitan dengan keamanan, kirimkan access token ke API Anda dan validasi di sana:
import { createRemoteJWKSet, jwtVerify } from 'jose';
const jwks = createRemoteJWKSet(new URL('https://example.eu.auth0.com/.well-known/jwks.json'));
export async function verifyAuth0AccessToken(token: string) {
const { payload } = await jwtVerify(token, jwks, {
issuer: 'https://example.eu.auth0.com/', // Auth0 issuers end with a slash
audience: 'https://api.example.com',
});
return payload; // payload.sub is the Auth0 user ID
}
Langkah 6: Refresh access token
import { SocialLogin } from '@capgo/capacitor-social-login';
export async function getValidAccessToken() {
const { isLoggedIn } = await SocialLogin.isLoggedIn({ provider: 'oauth2', providerId: 'auth0' });
if (!isLoggedIn) {
// access token expired: try the stored refresh token
try {
await SocialLogin.refresh({ provider: 'oauth2', options: { providerId: 'auth0' } });
} catch {
// refresh token expired, revoked or already rotated: sign in again
const loginResult = await signInWithAuth0();
if (!loginResult) throw new Error('Sign-in cancelled');
}
}
const { accessToken } = await SocialLogin.getAuthorizationCode({
provider: 'oauth2',
providerId: 'auth0',
});
return accessToken;
}
refresh ditolak jika refresh token kedaluwarsa atau dicabut. Dengan rotasi aktif, refresh token yang sudah digunakan juga akan gagal, jadi selalu tangani penolakan dengan mengirim pengguna kembali ke halaman sign in.
refresh menggunakan refresh token yang disimpan plugin saat login. Jika Anda menyimpan refresh token sendiri, panggil SocialLogin.refreshToken({ provider: 'oauth2', providerId: 'auth0', refreshToken }), yang mengembalikan respons token baru secara lengkap. Jika rotasi diaktifkan, simpan refresh token baru setiap kali.
Plugin menyimpan salinan token di penyimpanan privat aplikasi. Jika tinjauan keamanan Anda meminta Keychain atau Keystore, simpan refresh token dengan NativeBiometric.setData({ key, value }) dari @capgo/capacitor-native-biometric dan lewati ke refreshToken Anda sendiri. Kami penyimpanan token aman kami membandingkan opsi-opsinya.
Langkah 7: Keluar
await SocialLogin.logout({ provider: 'oauth2', providerId: 'auth0' });
Plugin menghapus token yang tersimpan, lalu membuka logoutUrl dengan id_token_hint dan post_logout_redirect_uri sehingga Auth0 menghapus cookie sesi. Auth0’s /oidc/logout endpoint memahami parameter tersebut, dan target redirect harus terdaftar di URL Logout yang Diizinkan.
Di iOS dan Android, halaman end-session terbuka di browser sistem, sehingga pengguna sesaat keluar dari aplikasi. Jika Anda hanya ingin logout lokal, lewati logoutUrl dan berikan prompt: 'login' pada sign-in berikutnya agar sesi Auth0 yang tersimpan tidak langsung login ulang. Setting iosPrefersEphemeralSession: true juga menghindari cookie bersama di iOS, dengan konsekuensi tidak ada SSO antar aplikasi.
Pemecahan Masalah
| Error | Penyebab | Perbaikan |
|---|---|---|
Callback URL mismatch |
Redirect URL tidak ada di Allowed Callback URLs | Salin nilai persis dari code ke dashboard, periksa scheme dan host |
Unauthorized atau invalid_client pada /oauth/token |
Tipe aplikasi bukan Native, atau metode auth bukan None | Buat ulang sebagai Native, atur auth token endpoint ke None |
Tidak refreshToken dalam hasil |
offline_access hilang atau API tidak mengizinkan akses offline |
Tambahkan scope, aktifkan Allow Offline Access, aktifkan rotasi |
| Access token tidak dapat diverifikasi oleh API | Tidak audience dikirim |
Tambah audience di additionalParameters |
| Aplikasi tidak terbuka kembali setelah login di Android | Scheme atau host intent filter tidak cocok redirectUrl |
Cocokkan com.example.app dan oauth persis |
OAuth2 provider "auth0" not configured |
login dipanggil sebelum initialize atau key tidak cocok |
Await initialize pada startup, gunakan yang sama providerId |
| Halaman logout tetap terbuka | post_logout_redirect_uri tidak ada di Allowed Logout URLs |
Tambahkan, atau gunakan logout lokal saja |
| Error CORS web saat token exchange | Origin tidak ada di Allowed Web Origins | Tambahkan web origin, atau gunakan aplikasi SPA untuk web |
Atur logsEnabled: true di konfigurasi provider untuk mencetak URL yang dihasilkan dan detail token exchange saat Anda debug.
Rilis perbaikan auth tanpa lewat store
Mengubah scopes, audience, atau error handling hanya untuk TypeScript. Dengan Live updates Capgo Anda dapat menerapkan perbaikan tersebut ke pengguna pada hari yang sama. Perubahan native seperti intent filter baru tetap membutuhkan binary baru, yang Build Capgo dapat dihasilkan di cloud.