Lebih Lanjut ke Konten Utama

Cara Menggunakan Autentikasi Lebih Baik di Aplikasi Capacitor (Pedoman 2026)

Gunakan Otorisasi Lebih Baik di Aplikasi Capacitor 8: asal yang dipercaya, token bearer daripada cookie, email dan kata sandi, sign-in Google dan Apple native, dan perbaikan.

Kredit Artikel

Martin Donadieu

Penulis

Valeria

Pengulas

Jordan

Editor

Cara Menggunakan Otorisasi Lebih Baik di Aplikasi Capacitor (Petunjuk 2026)

Untuk menggunakan Better Auth di sebuah aplikasi Capacitor, instal plugin. better-auth masukkan klien web Anda di code, arahkan ke server Better Auth Anda, tambahkan asal Capacitor ("capacitor://localhost Pilih https://localhost On Android) ke trustedOriginsdan beralih dari cookie ke token bearer dengan bearer plugin. Email dan kata sandi berfungsi melalui SDK secara langsung. Untuk Google dan Apple, dapatkan token ID dengan plugin native seperti @capgo/capacitor-social-login dan berikan kepadanya authClient.signIn.social({ idToken }).

Aplikasi Capacitor adalah aplikasi web yang disajikan dari asal lokal di dalam WebView native. Dibandingkan dengan situs web normal, tiga hal yang berbeda:

Apa yang berubah ketika Better Auth berjalan di dalam Capacitor

A Capacitor app is a web app served from a local origin inside a native WebView. Compared to a normal website, three things are different:

Topic Pada sebuah situs web In a Capacitor app
]} https://app.example.com capacitor://localhost Origin https://localhost (iOS)
Pelayan Autentikasi Seringnya sama situs, kuki bekerja dengan baik Domain berbeda, kuki ketiga diblokir oleh WKWebView
Redirect OAuth Redirect penuh halaman baik Redirect meninggalkan aplikasi bundel, Google menghalangi WebViews

Pembetulan adalah: percayai asal Capacitor, gunakan token bearer, dan gunakan plugin native untuk login sosial.

Langkah 1: Konfigurasi Pelayan Autentikasi yang Lebih Baik

Contoh ini menggunakan Hono, tetapi konfigurasi Autentikasi yang Lebih Baik sama untuk Express, pengaturan jalur Next.js atau runtime lainnya.

bun add better-auth hono
// auth.ts
import { betterAuth } from 'better-auth';
import { bearer } from 'better-auth/plugins';
import { db } from './db'; // your Drizzle, Prisma, Kysely or pg instance

export const auth = betterAuth({
  baseURL: process.env.BETTER_AUTH_URL, // https://auth.example.com
  database: db,
  emailAndPassword: {
    enabled: true,
  },
  socialProviders: {
    google: {
      clientId: process.env.GOOGLE_WEB_CLIENT_ID as string,
      clientSecret: process.env.GOOGLE_CLIENT_SECRET as string,
    },
    apple: {
      clientId: process.env.APPLE_SERVICE_ID as string,
      clientSecret: process.env.APPLE_CLIENT_SECRET as string,
      appBundleIdentifier: process.env.APPLE_BUNDLE_ID as string, // com.example.app
    },
  },
  trustedOrigins: [
    'capacitor://localhost', // iOS WebView
    'https://localhost', // Android WebView (androidScheme https, the default)
    'https://app.example.com', // your web build
    'https://appleid.apple.com',
  ],
  plugins: [bearer()],
});

appBundleIdentifier hal yang penting untuk Apple. Token dari sheet native iOS membawa ID aplikasi bundel sebagai audiens, sedangkan token web dan Android membawa ID Layanan. Autentikasi yang Lebih Baik menggunakan bidang ini untuk menerima kedua.

Pasang pengaturan handler dan izinkan CORS dari asal aplikasi. Terbuka set-auth-token header, jika tidak, klien tidak akan melihat token bearer:

// server.ts
import { Hono } from 'hono';
import { cors } from 'hono/cors';
import { auth } from './auth';

const app = new Hono();

app.use(
  '/api/auth/*',
  cors({
    origin: ['capacitor://localhost', 'https://localhost', 'https://app.example.com'],
    allowHeaders: ['Content-Type', 'Authorization'],
    allowMethods: ['GET', 'POST', 'OPTIONS'],
    exposeHeaders: ['set-auth-token'],
    credentials: true,
  }),
);

app.on(['GET', 'POST'], '/api/auth/*', (c) => auth.handler(c.req.raw));

export default app;

Run bunx @better-auth/cli migrate (or generate Step 2: Buat klien autentikasi di aplikasi

Langkah 2: Buatlah klien autentikasi di aplikasi

bun add better-auth @capgo/capacitor-native-biometric
bunx cap sync

Simpan token sesi di Keychain atau Keystore, dan simpan salinan di memori agar klien dapat membacanya secara sinkron.

// auth-client.ts
import { createAuthClient } from 'better-auth/client';
import { NativeBiometric } from '@capgo/capacitor-native-biometric';

const TOKEN_KEY = 'session.token';
let sessionToken = '';

export async function loadSessionToken() {
  try {
    const { value } = await NativeBiometric.getData({ key: TOKEN_KEY });
    sessionToken = value;
  } catch {
    sessionToken = '';
  }
}

async function saveSessionToken(token: string) {
  sessionToken = token;
  if (token) {
    await NativeBiometric.setData({ key: TOKEN_KEY, value: token });
  } else {
    await NativeBiometric.deleteData({ key: TOKEN_KEY }).catch(() => {});
  }
}

export const authClient = createAuthClient({
  baseURL: 'https://auth.example.com',
  fetchOptions: {
    auth: {
      type: 'Bearer',
      token: () => sessionToken,
    },
    onSuccess: async (ctx) => {
      const token = ctx.response.headers.get('set-auth-token');
      if (token) await saveSessionToken(token);
    },
  },
});

export async function clearSession() {
  await saveSessionToken('');
}

Call await loadSessionToken() sebelum aplikasi Anda dirender, kemudian authClient.getSession() dari subpath yang sesuai (

import { authClient, loadSessionToken } from './auth-client';

await loadSessionToken();
const { data: session } = await authClient.getSession();
if (session) {
  console.log('Signed in as', session.user.email);
}

Jika Anda menggunakan React, Vue, Svelte atau Solid, import createAuthClient Sebelum aplikasi Anda menampilkan konten, lalubetter-auth/react, better-auth/vueuntuk mengembalikan pengguna: useSession hook. fetchOptions tetaplah sama. The setData dan getData metode ini hanya tersedia untuk native. Pada web, jatuh kembali ke cookies atau sessionStorage menggunakan Capacitor.isNativePlatform().

Langkah 3: Email dan kata sandi

tidak perlu plugin. Ini adalah panggilan HTTP biasa.

import { authClient, clearSession } from './auth-client';

export async function signUp(email: string, password: string, name: string) {
  const { data, error } = await authClient.signUp.email({ email, password, name });
  if (error) throw new Error(error.message);
  return data;
}

export async function signIn(email: string, password: string) {
  const { data, error } = await authClient.signIn.email({ email, password });
  if (error) throw new Error(error.message);
  return data;
}

export async function signOut() {
  await authClient.signOut();
  await clearSession();
}

Untuk verifikasi email dan pengaturan ulang kata sandi, Better Auth mengirimkan tautan yang membuka URL. Poin callbackURL ke halaman pada domain Anda yang juga telah dikonfigurasi sebagai iOS Universal Link dan Android App Link, sehingga tautan membuka aplikasi di ponsel dan situs web di tempat lain.

Langkah 4: Pengenalan Google native

Konfigurasi Google seperti yang dijelaskan di Bagaimana mengenali Google menggunakan Capacitor, then:

import { SocialLogin } from '@capgo/capacitor-social-login';
import { authClient } from './auth-client';

await SocialLogin.initialize({
  google: {
    webClientId: 'WEB_CLIENT_ID.apps.googleusercontent.com',
    iOSClientId: 'IOS_CLIENT_ID.apps.googleusercontent.com',
    mode: 'online', // Better Auth needs the idToken, offline mode only returns a code
  },
});

export async function signInWithGoogle() {
  const { result } = await SocialLogin.login({ provider: 'google', options: {} });

  if (result.responseType !== 'online' || !result.idToken) {
    throw new Error('Google did not return an ID token');
  }

  const { data, error } = await authClient.signIn.social({
    provider: 'google',
    idToken: {
      token: result.idToken,
      accessToken: result.accessToken?.token,
    },
  });
  if (error) throw new Error(error.message);
  return data;
}

Better Auth memeriksa token terhadap kunci Google dan ID klien yang dikonfigurasi, membuat atau menghubungkan pengguna, dan mengembalikan sebuah sesi. Token pengemban datang dalam set-auth-token header dan hook Anda menyimpannya. onSuccess Langkah 5: Sign-in Apple asli

Konfigurasi Apple seperti yang dijelaskan dalam

Bagaimana untuk sign in dengan Apple menggunakan __CAPGO_KEEP_0__ Cara masuk dengan Apple menggunakan CapacitorBuatlah sebuah nonce, kirimkan ke Apple, dan kirimkan nilai yang sama ke Better Auth:

import { SocialLogin } from '@capgo/capacitor-social-login';
import { authClient } from './auth-client';

export async function signInWithApple() {
  const nonce = crypto.randomUUID();

  const { result } = await SocialLogin.login({
    provider: 'apple',
    options: { scopes: ['email', 'name'], nonce },
  });

  if (!result.idToken) throw new Error('Apple did not return an ID token');

  const { data, error } = await authClient.signIn.social({
    provider: 'apple',
    idToken: {
      token: result.idToken,
      nonce,
      accessToken: result.accessToken?.token,
    },
  });
  if (error) throw new Error(error.message);
  return data;
}

Apple only shares the user’s name on the first authorization. If you want it on the user record, update the profile right after the first sign-in with result.profile.givenName and familyName.

Pada Facebook, pola yang sama berlaku. Pada iOS dengan Login Terbatas, Anda akan mendapatkan idTokenDi tempat lain, Anda melewati token akses. Integrasi Autentikasi Lebih Baik halaman memiliki contoh Facebook yang lengkap.

Langkah 6: Okta, Auth0, Entra ID dan penyedia OIDC lainnya

Autentikasi Lebih Baik genericOAuth Plugin membawa bantuan untuk Auth0, Okta, Keycloak, dan Microsoft Entra ID, serta konfigurasi manual untuk server OIDC apa pun. Pada pembangunan web, authClient.signIn.oauth2({ providerId }) berfungsi seperti di situs mana pun.

On iOS and Android the flow needs the system browser, because the provider login page must not load inside your WebView. The pattern that works:

  1. Aplikasi membuka URL masuk Better Auth Anda di browser sistem (misalnya dengan) SocialLogin.openSecureWindow atau plugin browser dalam aplikasi.
  2. Otorisasi Lebih Baik melakukan tarian OAuth dengan penyedia dan membuat sesi di server.
  3. Autentikasi Lebih Baik menjalankan tarian OAuth dengan penyedia dan membuat sesi di server. oneTimeToken plugin untuk hal ini) dan mengarahkan ke tautan dalam yang seperti com.example.app://auth?token=....
  4. Aplikasi memverifikasi token satu kali dengan klien autentikasi dan menerima sesi bearer normal.

Itu lebih banyak komponen daripada pengalihan token ID. Jika Anda hanya membutuhkan SSO bisnis dan tidak membutuhkan basis data pengguna Better Auth, masuk langsung ke penyedia adalah lebih sederhana, lihat di Okta, Auth0 dan ID Pengguna panduan.

Langkah 7: Lindungi API Anda dengan sesi

Sesungguhnya API Anda sendiri dapat membaca sesi dari token bearer dengan server API Better Auth:

import { Hono } from 'hono';
import { auth } from './auth';

const api = new Hono();

api.get('/me/orders', async (c) => {
  const session = await auth.api.getSession({ headers: c.req.raw.headers });
  if (!session) return c.json({ error: 'unauthorized' }, 401);
  return c.json(await listOrders(session.user.id));
});

Plugin bearer membuat getSession menerima Authorization: Bearer <token> dengan cara yang sama seperti menerima cookie.

Troubleshooting

Pertanyaan Penyebab Pemecahan
Invalid origin atau 403 pada saat login Capacitor asal tidak dipercaya Tambahkan capacitor://localhost dan https://localhost ke trustedOrigins
Error CORS di konsol WebView Server CORS tidak menyertakan asal aplikasi Tambahkan ke middleware CORS Anda, izinkan Authorization
Berhasil masuk tetapi getSession kembali null Mengandalkan cookie di domain yang berbeda Pakai plugin bearer dan kirimkan token
set-auth-token selalu null Kepala tidak terbuka Tambahkan exposeHeaders: ['set-auth-token'] CORS
ke CORS disallowed_useragent Halaman OAuth dimuat di dalam WebView Halaman OAuth dimuat di WebView idToken handoff
Token Google ID ditolak Audience tidak sesuai dengan ID klien yang dikonfigurasi Ukurlah token dengan SocialLogin.decodeIdToken dan bandingkan aud dengan clientId
Token ID Apple ditolak pada iOS Audience adalah ID paket Setel appBundleIdentifier dalam penyedia Apple
dalam penyedia Apple Nonce yang berbeda dikirim ke Apple dan Better Auth Buat sekali, gunakan kembali nilai yang sama
Kehilangan Sesi setelah aplikasi di-restart Token disimpan hanya di memori Simpan dengan setData dan muat sebelum permintaan pertama

Mengembangkan sisi mobile

Perubahan autentikasi jarang asli. Asal-usul yang dipercaya dan penyedia adalah konfigurasi server, dan klien code adalah TypeScript, sehingga sebagian besar perbaikan dapat dikirim melalui Capgo pembaruan hidup Anda hanya perlu binary baru ketika menambahkan plugin native atau mengubah skema URL.

Update Terus untuk Aplikasi Capacitor

Ketika bug layer web masih aktif, kirimkan perbaikan melalui Capgo daripada menunggu hari-hari untuk persetujuan toko aplikasi. Pengguna mendapatkan update di latar belakang sementara perubahan native tetap dalam jalur review normal.

Terbaru dari Blog Kami

Aplikasi Capgo memberikan Anda wawasan terbaik yang Anda butuhkan untuk membuat aplikasi mobile profesional sejati.