Lompat ke konten utama

Cara Sign In dengan Okta Menggunakan Capacitor

Hubungkan Okta ke aplikasi Capacitor 8 dengan OIDC dan PKCE: buat integrasi native app, atur redirect URI, refresh token, logout, dan perbaiki error Okta.

Cara Sign In dengan Okta Menggunakan Capacitor

Untuk sign in dengan Okta di aplikasi Capacitor, buatlah sebuah Aplikasi Native OIDC di Okta Admin Console, daftarkan sign-in redirect URI seperti com.example.app://oauth/okta, dan jalankan flow otorisasi code dengan PKCE di browser sistem. Dengan @capgo/capacitor-social-login Anda cukup konfigurasi Okta sekali dengan issuer dan client ID, lalu panggil SocialLogin.login({ provider: 'oauth2', options: { providerId: 'okta' } }).

Panduan ini membahas integrasi aplikasi Okta, kebijakan authorization server, plugin code untuk iOS, Android, dan web, token refresh, profil pengguna, logout, serta error Okta yang paling sering muncul. Ditujukan untuk Capacitor 8 per Oktober 2026.

Yang Anda butuhkan

  • Okta org (Workforce Identity atau Customer Identity) dengan akses admin untuk membuat integrasi aplikasi.
  • Aplikasi Capacitor 8.
  • Capacitor Anda appId, yang akan Anda gunakan kembali sebagai redirect scheme.
  • Opsional, backend API untuk memvalidasi Okta access token.

Cara kerja login Okta di aplikasi Capacitor

Aplikasi Anda tidak akan pernah menampilkan form password. Aplikasi akan membuka halaman sign-in Okta di browser yang aman, Okta menangani MFA dan kebijakan, lalu redirect kembali ke aplikasi Anda dengan code. Aplikasi kemudian menukar code beserta PKCE verifier untuk mendapatkan token.

Platform Browser Yang Anda konfigurasi
iOS ASWebAuthenticationSession Tidak ada di Info.plist
Android Chrome Custom Tabs dengan androidUseCustomTabs: true (WebView secara default) Intent filter untuk redirect scheme
Web Popup atau redirect Trusted Origin untuk CORS

Gunakan Custom Tabs di Android. Okta Verify, FastPass, dan passkeys bekerja lebih baik di browser sistem daripada di WebView, dan cookie SSO juga tersinkronisasi dengan Chrome.

Langkah 1: Buat integrasi aplikasi Okta

  1. Di Okta Admin Console, buka Applications > Applications > Create App Integration.
  2. Pilih OIDC - OpenID Connect dan Aplikasi Native.
  3. Beri nama, lalu di bagian Tipe grant keep Otorisasi Code dan centang Refresh Token agar user tetap dalam kondisi signed in.
  4. URI pengalihan sign-in: com.example.app://oauth/okta. Tambahkan https://app.example.com/auth/callback jika Anda merilis web build.
  5. URI pengalihan sign-out: com.example.app://oauth/logout (dan URL web jika diperlukan).
  6. Assignments: pilih siapa yang bisa menggunakan aplikasi. User yang tidak di-assign akan mendapat error saat sign-in.
  7. Simpan, lalu salin Client ID. Di bawah Kredensial Klien, autentikasi client harus None dan Wajibkan PKCE harus diaktifkan.

Okta memerlukan native redirect URI dengan private-use scheme dalam format reverse-domain. Bundle ID atau application ID Anda bisa digunakan.

Periksa authorization server

Buka Keamanan > API > Server Otorisasi. Sebagian besar setup menggunakan default server otorisasi kustom, issuer https://your-org.okta.com/oauth2/default.

Issuer Gunakan saat
https://your-org.okta.com/oauth2/default (custom) API Anda memvalidasi access token, Anda butuh custom scope atau claim
https://your-org.okta.com (org) Anda hanya butuh ID token atau panggil Okta API

Open the server’s Kebijakan Akses server. Harus ada policy yang ditujukan ke app Anda (atau All clients) dengan rule yang mengizinkan Otorisasi Code grant, dan Refresh Token jika Anda menggunakannya. Aturan yang hilang akan memicu “Policy evaluation failed for this request”.

Trusted Origins untuk web

Jika Anda menjalankan code yang sama di web, tambahkan web origin Anda di bawah Keamanan > API > Trusted Origins dengan CORS yang dicentang. Tanpa itu, browser akan memblokir request token.

Langkah 2: Instal plugin

bun add @capgo/capacitor-social-login
bunx cap sync

Jika Okta adalah satu-satunya provider, matikan bundled social SDK di capacitor.config.ts:

plugins: {
  SocialLogin: {
    providers: { google: false, facebook: false, apple: false, twitter: false },
  },
},

Langkah 3: Tambahkan Android redirect intent filter

Di android/app/src/main/AndroidManifest.xml, di dalam MainActivity 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.app" android:host="oauth" />
</intent-filter>

MainActivity harus tetap android:launchMode="singleTask", yang merupakan default Capacitor, sehingga redirect masuk ke activity yang sedang berjalan.

Langkah 4: Inisialisasi Okta

import { Capacitor } from '@capacitor/core';
import { SocialLogin } from '@capgo/capacitor-social-login';

const OKTA_ISSUER = 'https://your-org.okta.com/oauth2/default';
const isWeb = Capacitor.getPlatform() === 'web';

export async function initAuth() {
  await SocialLogin.initialize({
    oauth2: {
      okta: {
        appId: 'YOUR_OKTA_CLIENT_ID',
        authorizationBaseUrl: `${OKTA_ISSUER}/v1/authorize`,
        accessTokenEndpoint: `${OKTA_ISSUER}/v1/token`,
        resourceUrl: `${OKTA_ISSUER}/v1/userinfo`,
        redirectUrl: isWeb
          ? 'https://app.example.com/auth/callback'
          : 'com.example.app://oauth/okta',
        scope: 'openid profile email offline_access',
        pkceEnabled: true,
        logoutUrl: `${OKTA_ISSUER}/v1/logout`,
        postLogoutRedirectUrl: isWeb
          ? 'https://app.example.com/'
          : 'com.example.app://oauth/logout',
        androidUseCustomTabs: true,
      },
    },
  });
}

Alternatif lebih singkat: set issuerUrl: OKTA_ISSUER dan hapus URL endpoint. Plugin akan memuat /.well-known/openid-configuration dan mengisinya. Tim yang migrasi dari Ionic Auth Connect bisa menggunakan SocialLoginAuthConnect dengan okta preset (issuer, clientId, redirectUrl), yang dibahas di panduan migrasi.

Langkah 5: Sign in dan baca profil

import { SocialLogin } from '@capgo/capacitor-social-login';

export async function signInWithOkta() {
  try {
    const { result } = await SocialLogin.login({
      provider: 'oauth2',
      options: { providerId: 'okta' },
    });

    const profile = result.resourceData as {
      sub: string;
      email?: string;
      name?: string;
      preferred_username?: string;
    } | null;

    return {
      accessToken: result.accessToken?.token,
      idToken: result.idToken,
      refreshToken: result.refreshToken,
      scopes: result.scope,
      profile,
    };
  } catch (error: any) {
    if (error?.code === 'USER_CANCELLED') return null;
    throw error;
  }
}

resourceData berisi JSON yang dikembalikan oleh /userinfo endpoint, jadi Anda bisa mendapatkan profil tanpa request tambahan. Untuk membaca ID token claims guna ditampilkan, gunakan SocialLogin.decodeIdToken({ idToken }). Pemanggilan tersebut tidak memverifikasi signature.

Opsi login yang perlu diketahui:

  • loginHint mengisi otomatis username.
  • prompt: 'login' memaksa re-authentication meskipun ada sesi Okta yang aktif.
  • additionalParameters: { idp: '0oa...' } langsung mengarahkan ke identity provider tertentu yang dikonfigurasi di Okta.

Di web dengan flow: 'redirect', panggil SocialLogin.handleRedirectCallback() pada callback page untuk menyelesaikan exchange.

Langkah 6: Validasi token Okta di API Anda

import { createRemoteJWKSet, jwtVerify } from 'jose';

const ISSUER = 'https://your-org.okta.com/oauth2/default';
const jwks = createRemoteJWKSet(new URL(`${ISSUER}/v1/keys`));

export async function verifyOktaAccessToken(token: string) {
  const { payload } = await jwtVerify(token, jwks, {
    issuer: ISSUER,
    audience: 'api://default', // the Audience value of your authorization server
  });
  return payload; // payload.uid is the Okta user ID, payload.sub the login
}

Temukan audience pada authorization server Settings pada authorization server. Jangan validasi access token dari org authorization server di API Anda. Okta tidak mendukung hal tersebut.

Langkah 7: Refresh token

import { SocialLogin } from '@capgo/capacitor-social-login';

export async function ensureFreshOktaToken() {
  const { isLoggedIn } = await SocialLogin.isLoggedIn({ provider: 'oauth2', providerId: 'okta' });
  if (!isLoggedIn) {
    await SocialLogin.refresh({ provider: 'oauth2', options: { providerId: 'okta' } });
  }
  const { accessToken } = await SocialLogin.getAuthorizationCode({ provider: 'oauth2', providerId: 'okta' });
  return accessToken;
}

Jika refresh token sudah kedaluwarsa atau dicabut, refresh ditolak. Tangkap error tersebut dan arahkan user kembali ke signInWithOkta().

Cek Refresh Token pada bagian integrasi aplikasi. Dengan Rotasi token setelah setiap penggunaan, setiap refresh akan mengembalikan refresh token baru dan token lama akan berhenti berfungsi setelah masa grace period singkat. Plugin akan mengganti salinan yang tersimpan secara otomatis. Jika Anda menyimpan refresh token sendiri (misalnya di Keychain melalui @capgo/capacitor-native-biometric setData), gunakan SocialLogin.refreshToken({ provider: 'oauth2', providerId: 'okta', refreshToken }) dan simpan nilai yang dikembalikan.

Langkah 8: Sign out

await SocialLogin.logout({ provider: 'oauth2', providerId: 'okta' });

Plugin akan menghapus token yang tersimpan, lalu membuka /v1/logout dengan id_token_hint dan post_logout_redirect_uri. Okta mengakhiri sesi dan mengalihkan ke URI sign-out Anda, yang harus terdaftar di integrasi aplikasi. Pada mobile, halaman logout akan terbuka di browser sistem.

Untuk mencabut refresh token di sisi server juga, panggil /v1/revoke endpoint Okta dari backend atau aplikasi Anda sebelum logout. Lihat panduan pencabutan token kami untuk polanya.

Troubleshooting

Error Penyebab Solusi
invalid_request: The 'redirect_uri' parameter must be a Login redirect URI in the client app settings Redirect tidak terdaftar Tambahkan URI yang tepat ke Sign-in redirect URIs
User is not assigned to the client application Assignment tidak ditemukan Assign user atau group di bagian Assignments
Policy evaluation failed for this request Tidak ada aturan policy untuk client atau grant ini Tambahkan policy dan rule pada authorization server
invalid_client pada token endpoint App bertipe Web atau SPA, atau auth method bukan None Gunakan Native app dengan client authentication None
Tidak ada refresh token Refresh Token grant mati, offline_access hilang, atau diblokir rule Aktifkan grant, tambah scope, izinkan di rule
API menolak token dengan issuer salah Token berasal dari server org Gunakan custom authorization server issuer
Web: error CORS pada /v1/token Origin tidak dipercaya Tambah Trusted Origin dengan CORS
Android tetap di browser setelah login Ketidakcocokan intent filter Cocokkan scheme dan host ke redirectUrl

Aktifkan logsEnabled: true pada konfigurasi provider saat debugging untuk melihat URL otorisasi dan respons token di native logs.

Meluncurkan perubahan Okta

Pelanggan Enterprise sering mengubah kebijakan atau claims setelah peluncuran. Perubahan sisi client seperti scope, penanganan claim, atau layar error dapat dikirim dengan Capgo live updates daripada melalui review store penuh. Bagian native (intent filter, scheme baru) tetap memerlukan build baru.

Live update untuk aplikasi Capacitor

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

Terbaru dari Blog kami

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