---
description: Learn how to add Okta authentication to your Capacitor app using the OAuth plugin with PKCE support on Android, iOS, and web.
title: How to Sign In with Okta Using Capacitor - Capawesome
image: https://capawesome.io/docs/assets/images/social/blog/how-to-sign-in-with-okta-using-capacitor.png
---

[ Skip to content](#how-to-sign-in-with-okta-using-capacitor) 

[ 🔐 Introducing the **Capacitor Vault** plugin — store secrets behind biometrics or a device passcode.](/blog/announcing-the-capacitor-vault-plugin/) 

* [  SDKs ](/docs/sdks/)
* [  Formbricks ](/docs/sdks/capacitor/formbricks/)
* [  Geocoder ](/docs/sdks/capacitor/geocoder/)
* [  Google Sign-In ](/docs/sdks/capacitor/google-sign-in/)
* [  Grafana Faro ](/docs/sdks/capacitor/grafana-faro/)
* [  libSQL ](/docs/sdks/capacitor/libsql/)
* [  Live Update ](/docs/sdks/capacitor/live-update/)
* [  Managed Configurations ](/docs/sdks/capacitor/managed-configurations/)
* [  Media Session ](/docs/sdks/capacitor/media-session/)
* [  ML Kit ](/docs/sdks/capacitor/mlkit/)
* [  Navigation Bar ](/docs/sdks/capacitor/navigation-bar/)
* [  NFC ](/docs/sdks/capacitor/nfc/)
* [  OAuth ](/docs/sdks/capacitor/oauth/)
* [  Pedometer ](/docs/sdks/capacitor/pedometer/)
* [  Photo Editor ](/docs/sdks/capacitor/photo-editor/)
* [  PostHog ](/docs/sdks/capacitor/posthog/)
* [  Printer ](/docs/sdks/capacitor/printer/)
* [  Purchases ](/docs/sdks/capacitor/purchases/)
* [  RealtimeKit ](/docs/sdks/capacitor/realtimekit/)
* [  Screen Orientation ](/docs/sdks/capacitor/screen-orientation/)
* [  Screenshot ](/docs/sdks/capacitor/screenshot/)
* [  Secure Preferences ](/docs/sdks/capacitor/secure-preferences/)
* [  Speech Recognition ](/docs/sdks/capacitor/speech-recognition/)
* [  Speech Synthesis ](/docs/sdks/capacitor/speech-synthesis/)
* [  Share Target ](/docs/sdks/capacitor/share-target/)
* [  Square Mobile Payments ](/docs/sdks/capacitor/square-mobile-payments/)
* [  SQLite ](/docs/sdks/capacitor/sqlite/)
* [  Superwall ](/docs/sdks/capacitor/superwall/)
* [  Torch ](/docs/sdks/capacitor/torch/)
* [  Vault ](/docs/sdks/capacitor/vault/)
* [  Wifi ](/docs/sdks/capacitor/wifi/)
* [  Zip ](/docs/sdks/capacitor/zip/)
* [  Cordova ](/docs/sdks/cordova/)
* [  Cloud ](/docs/cloud/)
* [  Integrations ](/docs/cloud/live-updates/integrations/)
* Concepts
* Reference
* [  Troubleshooting ](/docs/cloud/live-updates/troubleshooting/)
* [  FAQ ](/docs/cloud/live-updates/faq/)
* [  Native Builds ](/docs/cloud/native-builds/)
* [  Set Up Environments ](/docs/cloud/native-builds/environments/)
* [  Overwrite Native Configurations ](/docs/cloud/native-builds/native-configurations/)
* [  Auto-Increment Build Numbers ](/docs/cloud/native-builds/auto-incrementing-build-numbers/)
* [  Configure the Web Build Script ](/docs/cloud/native-builds/web-build-script/)
* [  Build from a Monorepo ](/docs/cloud/native-builds/monorepo/)
* [  Use pnpm or Yarn ](/docs/cloud/native-builds/package-managers/)
* [  Install Private npm Packages ](/docs/cloud/native-builds/npm-private-registry/)
* [  Override the Java Version ](/docs/cloud/native-builds/override-java-version/)
* [  Custom iOS Provisioning Profiles ](/docs/cloud/native-builds/custom-ios-provisioning-profiles/)
* [  Build without Git ](/docs/cloud/native-builds/build-without-git/)
* [  Access Git Behind a Firewall ](/docs/cloud/native-builds/firewall-access/)
* [  Integrations ](/docs/cloud/native-builds/integrations/)
* Reference
* [  Troubleshooting ](/docs/cloud/native-builds/troubleshooting/)
* [  FAQ ](/docs/cloud/native-builds/faq/)
* [  App Store Publishing ](/docs/cloud/app-store-publishing/)
* [  Submit a Build ](/docs/cloud/app-store-publishing/submit-a-build/)
* [  Submit Automatically After a Build ](/docs/cloud/app-store-publishing/submit-automatically/)
* [  Troubleshooting ](/docs/cloud/app-store-publishing/troubleshooting/)
* [  FAQ ](/docs/cloud/app-store-publishing/faq/)
* [  Automations ](/docs/cloud/automations/)
* [  Reference ](/docs/cloud/automations/reference/)
* [  Troubleshooting ](/docs/cloud/automations/troubleshooting/)
* [  FAQ ](/docs/cloud/automations/faq/)
* [  Assist ](/docs/cloud/assist/)
* [  CLI ](/docs/cloud/cli/)
* APIs and SDKs
* [  Webhooks ](/docs/cloud/webhooks/)
* [  Integrations ](/docs/cloud/integrations/)
* Account
* [  Organization ](/docs/cloud/organizations/)
* [  Two-Factor Enforcement ](/docs/cloud/organizations/two-factor-authentication/)
* [  Audit Logs ](/docs/cloud/organizations/audit-logs/)
* [  Billing ](/docs/cloud/organizations/billing/)
* [  License Keys ](/docs/cloud/license-keys/)
* [  AI ](/docs/ai/)
* [  Insiders ](/docs/insiders/)
* [  Billing & Plans ](/docs/insiders/billing-and-plans/)
* [  FAQ ](/docs/insiders/faq/)
* [  License ](https://capawesome.io/legal/eula/)
* [  Support ](/docs/support/)
* [  Contributing ](/docs/contributing/)
* Contributing code
* [  Code of Conduct ](/docs/contributing/code-of-conduct/)
* [  Questions ](https://docs.github.com/en/discussions/collaborating-with-your-community-using-discussions/participating-in-a-discussion#creating-a-discussion)
* [  Blog ](/blog/)
* Categories

* [  Implementing Authentication ](#implementing-authentication)
* [  Fetching the User Profile ](#fetching-the-user-profile)
* [  Try Capawesome Cloud ](#try-capawesome-cloud)
* [  Conclusion ](#conclusion)

* Related links

# How to Sign In with Okta Using Capacitor[¶](#how-to-sign-in-with-okta-using-capacitor "Permanent link")

[Okta](https://www.okta.com/) is a widely used identity platform that powers single sign-on (SSO) and user management for thousands of organizations. If you need to add Okta authentication to a Capacitor app, the [Capacitor OAuth plugin](/docs/sdks/capacitor/oauth/) supports the Authorization Code flow with PKCE out of the box. In this guide, you'll learn how to register your app in Okta, implement sign-in and sign-out, manage tokens, and retrieve user profile data on Android, iOS, and web. This is also a great alternative to [Ionic Auth Connect](https://ionic.io/docs/auth-connect/okta) for teams looking for a lightweight, open approach.

[ ![Build and deploy your Capacitor app with Capawesome Cloud](../../assets/external/cloud.capawesome.io/assets/banners/cloud-build-and-deploy-capacitor-apps.69628c3f.png) ](/) 

## Bonus: Video Tutorial and Demo App[¶](#bonus-video-tutorial-and-demo-app "Permanent link")

This tutorial shows the full OAuth plugin flow in a Capacitor app, including PKCE, redirect handling, token lifecycle management, and native/web behavior. The same architecture applies directly to Okta with provider-specific configuration values.

* **[OAuth Demo App](https://github.com/capawesome-team/capacitor-oauth-demo)** — A practical reference implementation you can adapt to Okta by replacing issuer and client configuration.

## Prerequisites[¶](#prerequisites "Permanent link")

Before getting started, make sure you have:

* An **Okta developer account**. You can [sign up for a free Okta developer account](https://developer.okta.com/signup/) if you don't already have one.
* A **Capacitor app** with the [Capacitor OAuth plugin](/docs/sdks/capacitor/oauth/) installed. For installation instructions, head over to the [Installation](/docs/sdks/capacitor/oauth/#installation) section in the plugin documentation.

## Setting Up Okta[¶](#setting-up-okta "Permanent link")

### Creating an Application[¶](#creating-an-application "Permanent link")

To get started, you need to register a new application in the Okta Admin Console:

1. Sign in to your [Okta Admin Console](https://login.okta.com/).
2. Go to **Applications** \> **Applications** and click **Create App Integration**.
3. Select **OIDC - OpenID Connect** as the sign-in method.
4. Choose **Native Application** as the application type and click **Next**.
5. Give your application a **Name** (e.g. `My Capacitor App`).
6. Under **Grant type**, make sure **Authorization Code** and **Refresh Token** are selected.
7. Configure the **Sign-in redirect URIs** and **Sign-out redirect URIs** (see sections below).
8. Under **Assignments**, choose the appropriate controlled access option for your use case.
9. Click **Save**.
10. On the application's **General** tab, note the **Client ID** and your **Okta domain** (e.g. `dev-123456.okta.com`). You'll need both values later.

### Configuring Sign-in Redirect URIs[¶](#configuring-sign-in-redirect-uris "Permanent link")

Add a redirect URI for each platform your app supports. You can add multiple URIs in the **Sign-in redirect URIs** section of your application settings.

**Android and iOS**: Use a custom scheme based on your app's package name or bundle identifier:

`[](#%5F%5Fcodelineno-0-1)com.example.app://oauth/callback
`

**Web**: Use your local development URL:

`[](#%5F%5Fcodelineno-1-1)http://localhost:3000/oauth/callback
`

### Configuring Sign-out Redirect URIs[¶](#configuring-sign-out-redirect-uris "Permanent link")

Similarly, configure the **Sign-out redirect URIs** so Okta knows where to send users after they log out.

**Android and iOS**:

`[](#%5F%5Fcodelineno-2-1)com.example.app://oauth/logout
`

**Web**:

`[](#%5F%5Fcodelineno-3-1)http://localhost:3000/oauth/logout
`

## Implementing Authentication[¶](#implementing-authentication "Permanent link")

In the examples below, replace `{okta-domain}` with your Okta domain (e.g. `dev-123456.okta.com`) and `{client-id}` with your application's **Client ID**.

### Signing In[¶](#signing-in "Permanent link")

Kick off the OAuth flow using the [login(...)](/docs/sdks/capacitor/oauth/#login) method. The plugin fetches Okta's OpenID Connect discovery document automatically and takes care of the PKCE challenge:

`[](#%5F%5Fcodelineno-4-1)import { Oauth } from '@capawesome-team/capacitor-oauth';
[](#%5F%5Fcodelineno-4-2)
[](#%5F%5Fcodelineno-4-3)const login = async () => {
[](#%5F%5Fcodelineno-4-4)  const result = await Oauth.login({
[](#%5F%5Fcodelineno-4-5)    issuerUrl: 'https://{okta-domain}/oauth2/default',
[](#%5F%5Fcodelineno-4-6)    clientId: '{client-id}',
[](#%5F%5Fcodelineno-4-7)    redirectUrl: 'com.example.app://oauth/callback',
[](#%5F%5Fcodelineno-4-8)    scopes: ['openid', 'profile', 'email', 'offline_access'],
[](#%5F%5Fcodelineno-4-9)  });
[](#%5F%5Fcodelineno-4-10)  console.log('Access token:', result.accessToken);
[](#%5F%5Fcodelineno-4-11)  console.log('ID token:', result.idToken);
[](#%5F%5Fcodelineno-4-12)  console.log('Refresh token:', result.refreshToken);
[](#%5F%5Fcodelineno-4-13)};
`

Adding `offline_access` to the scopes ensures you receive a refresh token.

### Handling the Redirect Callback (Web)[¶](#handling-the-redirect-callback-web "Permanent link")

On the web, [login(...)](/docs/sdks/capacitor/oauth/#login) redirects the user to Okta's hosted login page. Once the user authenticates, Okta redirects them back to your app. Call [handleRedirectCallback()](/docs/sdks/capacitor/oauth/#handleredirectcallback) when the page loads to finish the token exchange:

`[](#%5F%5Fcodelineno-5-1)import { Oauth } from '@capawesome-team/capacitor-oauth';
[](#%5F%5Fcodelineno-5-2)import { Capacitor } from '@capacitor/core';
[](#%5F%5Fcodelineno-5-3)
[](#%5F%5Fcodelineno-5-4)const handleRedirectCallback = async () => {
[](#%5F%5Fcodelineno-5-5)  if (Capacitor.getPlatform() !== 'web') {
[](#%5F%5Fcodelineno-5-6)    return;
[](#%5F%5Fcodelineno-5-7)  }
[](#%5F%5Fcodelineno-5-8)  const url = new URL(window.location.href);
[](#%5F%5Fcodelineno-5-9)  if (!url.searchParams.has('code')) {
[](#%5F%5Fcodelineno-5-10)    return;
[](#%5F%5Fcodelineno-5-11)  }
[](#%5F%5Fcodelineno-5-12)  const result = await Oauth.handleRedirectCallback();
[](#%5F%5Fcodelineno-5-13)  console.log('Access token:', result.accessToken);
[](#%5F%5Fcodelineno-5-14)};
[](#%5F%5Fcodelineno-5-15)
[](#%5F%5Fcodelineno-5-16)handleRedirectCallback();
`

On Android and iOS, the redirect is handled natively, so this step only applies to the web.

### Refreshing the Access Token[¶](#refreshing-the-access-token "Permanent link")

Access tokens are short-lived by design. Use the [refreshToken(...)](/docs/sdks/capacitor/oauth/#refreshtoken) method to obtain a fresh access token without prompting the user to sign in again:

`[](#%5F%5Fcodelineno-6-1)import { Oauth } from '@capawesome-team/capacitor-oauth';
[](#%5F%5Fcodelineno-6-2)
[](#%5F%5Fcodelineno-6-3)const refreshToken = async () => {
[](#%5F%5Fcodelineno-6-4)  const result = await Oauth.refreshToken({
[](#%5F%5Fcodelineno-6-5)    issuerUrl: 'https://{okta-domain}/oauth2/default',
[](#%5F%5Fcodelineno-6-6)    clientId: '{client-id}',
[](#%5F%5Fcodelineno-6-7)    refreshToken: 'YOUR_REFRESH_TOKEN',
[](#%5F%5Fcodelineno-6-8)  });
[](#%5F%5Fcodelineno-6-9)  console.log('New access token:', result.accessToken);
[](#%5F%5Fcodelineno-6-10)};
`

### Decoding the ID Token[¶](#decoding-the-id-token "Permanent link")

Extract user profile claims from the ID token with the [decodeIdToken(...)](/docs/sdks/capacitor/oauth/#decodeidtoken) method:

`[](#%5F%5Fcodelineno-7-1)import { Oauth } from '@capawesome-team/capacitor-oauth';
[](#%5F%5Fcodelineno-7-2)
[](#%5F%5Fcodelineno-7-3)const decodeIdToken = async () => {
[](#%5F%5Fcodelineno-7-4)  const result = await Oauth.decodeIdToken({
[](#%5F%5Fcodelineno-7-5)    token: 'YOUR_ID_TOKEN',
[](#%5F%5Fcodelineno-7-6)  });
[](#%5F%5Fcodelineno-7-7)  console.log('Name:', result.payload.name);
[](#%5F%5Fcodelineno-7-8)  console.log('Email:', result.payload.email);
[](#%5F%5Fcodelineno-7-9)};
`

The token is decoded locally on the device. If you need server-side verification, validate the JWT on your backend instead.

### Signing Out[¶](#signing-out "Permanent link")

Terminate the session by calling the [logout(...)](/docs/sdks/capacitor/oauth/#logout) method:

`[](#%5F%5Fcodelineno-8-1)import { Oauth } from '@capawesome-team/capacitor-oauth';
[](#%5F%5Fcodelineno-8-2)
[](#%5F%5Fcodelineno-8-3)const logout = async () => {
[](#%5F%5Fcodelineno-8-4)  await Oauth.logout({
[](#%5F%5Fcodelineno-8-5)    issuerUrl: 'https://{okta-domain}/oauth2/default',
[](#%5F%5Fcodelineno-8-6)    idToken: 'YOUR_ID_TOKEN',
[](#%5F%5Fcodelineno-8-7)    postLogoutRedirectUrl: 'com.example.app://oauth/logout',
[](#%5F%5Fcodelineno-8-8)  });
[](#%5F%5Fcodelineno-8-9)};
`

## Fetching the User Profile[¶](#fetching-the-user-profile "Permanent link")

You can also retrieve the authenticated user's profile directly from Okta's `/userinfo` endpoint using the access token:

`` [](#%5F%5Fcodelineno-9-1)import { Oauth } from '@capawesome-team/capacitor-oauth';
[](#%5F%5Fcodelineno-9-2)
[](#%5F%5Fcodelineno-9-3)const login = async () => {
[](#%5F%5Fcodelineno-9-4)  const result = await Oauth.login({
[](#%5F%5Fcodelineno-9-5)    issuerUrl: 'https://{okta-domain}/oauth2/default',
[](#%5F%5Fcodelineno-9-6)    clientId: '{client-id}',
[](#%5F%5Fcodelineno-9-7)    redirectUrl: 'com.example.app://oauth/callback',
[](#%5F%5Fcodelineno-9-8)    scopes: ['openid', 'profile', 'email', 'offline_access'],
[](#%5F%5Fcodelineno-9-9)  });
[](#%5F%5Fcodelineno-9-10)
[](#%5F%5Fcodelineno-9-11)  const response = await fetch(
[](#%5F%5Fcodelineno-9-12)    'https://{okta-domain}/oauth2/default/v1/userinfo',
[](#%5F%5Fcodelineno-9-13)    {
[](#%5F%5Fcodelineno-9-14)      headers: {
[](#%5F%5Fcodelineno-9-15)        Authorization: `Bearer ${result.accessToken}`,
[](#%5F%5Fcodelineno-9-16)      },
[](#%5F%5Fcodelineno-9-17)    },
[](#%5F%5Fcodelineno-9-18)  );
[](#%5F%5Fcodelineno-9-19)  const user = await response.json();
[](#%5F%5Fcodelineno-9-20)  console.log('Name:', user.name);
[](#%5F%5Fcodelineno-9-21)  console.log('Email:', user.email);
[](#%5F%5Fcodelineno-9-22)};
 ``

## Try Capawesome Cloud[¶](#try-capawesome-cloud "Permanent link")

If you're building Capacitor apps, [Capawesome Cloud](/) can help you ship faster with cloud-based native builds, over-the-air updates, and more.

[Try Capawesome Cloud Free](/)

## Conclusion[¶](#conclusion "Permanent link")

In this guide, you learned how to integrate Okta authentication into a Capacitor app using the [Capacitor OAuth plugin](/docs/sdks/capacitor/oauth/). We covered creating an Okta application, configuring redirect URIs, signing users in and out, refreshing tokens, and fetching profile data. The plugin handles the OIDC and PKCE details under the hood, so you can focus on your app.

For more details, check out the full [API Reference](/docs/sdks/capacitor/oauth/#api) for all available methods and options. You might also find the [How to Sign In with Azure Entra ID Using Capacitor](/blog/how-to-sign-in-with-azure-entra-id-using-capacitor/) guide helpful if you need to support multiple identity providers. If you have questions or run into issues, feel free to [create an issue](https://github.com/capawesome-team/capacitor-plugins/issues/new/choose) on [GitHub](https://github.com/capawesome-team/capacitor-plugins) or join the [Capawesome Discord server](https://discord.gg/VCXxSVjefW).

To stay up to date with the latest news, subscribe to the [Capawesome newsletter](/newsletter/).

June 8, 2026 

 Back to top 