Langsung ke konten utama

Cara Login dengan Auth0 Menggunakan Capacitor

Tambahkan login Auth0 ke aplikasi Capacitor 8 dengan OIDC dan PKCE: setup dashboard Auth0, URL callback, audience API, refresh token, logout, dan troubleshooting.

Auth0 Universal Login yang dibuka dari aplikasi Capacitor melalui browser sistem

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:

  1. Aplikasi menghasilkan PKCE verifier dan challenge, lalu membuka https://YOUR_TENANT/authorize di browser yang aman.
  2. Pengguna masuk (password, sosial, passkey, MFA, apa pun yang Anda konfigurasikan di Auth0).
  3. Auth0 mengalihkan ke URL callback Anda dengan satu kali code.
  4. Aplikasi menukarkan code dan PKCE verifier di /oauth/token untuk 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

  1. Di Dashboard Auth0, buka Aplikasi > Aplikasi > Buat Aplikasi.
  2. Pilih Native dan buat aplikasinya.
  3. Pada tab Pengaturan tab, catat Domain (contohnya example.eu.auth0.com) dan Client ID.
  4. 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:

  1. Di Pengaturan > Rotasi Token Refresh, aktifkan rotasi. Setiap refresh mengembalikan refresh token baru dan membatalkan yang lama.
  2. Atur masa berlaku absolut dan batas waktu inaktivitas yang sesuai dengan produk Anda.
  3. Jika Anda memanggil API Anda sendiri, buka Applications > APIs > API Anda > Settings dan aktifkan Izinkan Akses Offline.
  4. Minta offline_access scope 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.

Live updates untuk aplikasi Capacitor

Saat bug web-layer sudah live, kirim perbaikannya lewat Capgo alih-alih menunggu berhari-hari untuk persetujuan app store. Pengguna mendapat update di background, sementara perubahan native tetap mengikuti jalur review normal.

Terbaru dari Blog kami

Capgo memberikan insight terbaik yang Anda butuhkan untuk membuat aplikasi mobile yang benar-benar profesional.