애플리케이션에서 Okta로 로그인하려면 Capacitor 앱에서 OIDC 네이티브 애플리케이션 Okta 관리 콘솔에서 로그인 리다이렉트 URI와 같은 URI를 등록하세요. com.example.app://oauth/okta, 그리고 시스템 브라우저에서 PKCE를 사용하여 인증 code 흐름을 실행하세요. @capgo/capacitor-social-login Okta와 함께 구성하면 issuer와 client ID를 사용하여 한번만 Okta를 구성하면 됩니다. 그 다음에 SocialLogin.login({ provider: 'oauth2', options: { providerId: 'okta' } }).
이 가이드는 Okta 앱 통합, 인증 서버 정책, iOS, Android 및 웹용 플러그인 code, 토큰 갱신, 사용자 프로필, 로그아웃, 그리고 가장 자주 나타나는 Okta 오류에 대해 다룹니다. 이 가이드는 2026년 10월 현재 Capacitor 8을 지원합니다.
필요한 것
- Okta org (워크포스 아이덴티티 또는 고객 아이덴티티)와 관리자 권한이 있는 앱 통합을 생성할 수 있는 권한.
- Capacitor 8 앱.
- Capacitor
appId, 이 값을 다시 사용하여 리다이렉트 스키마로 사용합니다. - 선택적으로, Okta 접근 토큰을 검증하는 백엔드 API가 필요합니다.
Okta 로그인 방법은 Capacitor 앱에서 작동합니다.
앱은 비밀번호 입력 폼을 표시하지 않습니다. 대신, Okta 로그인 페이지를 안전한 브라우저에서 열고, Okta는 MFA 및 정책을 처리한 후 앱으로 리다이렉트합니다. 앱은 code를 사용하여 code와 PKCE verifier를 교환하여 토큰을 얻습니다.
| 플랫폼 | 브라우저 | 구성하는 항목 |
|---|---|---|
| iOS | ASWebAuthenticationSession |
설정할 항목이 없습니다 Info.plist |
| Android | Chrome Custom Tabs와 함께 androidUseCustomTabs: true (WebView 기본) |
리다이렉트 스키마를 위한 인텐트 필터 |
| 웹 | 팝업 또는 리다이렉트 | CORS에 대한 신뢰할 수 있는 원본 |
Android에서 Custom Tabs를 선호하세요. Okta Verify, FastPass 및 passkeys는 시스템 브라우저에서 임베디드 WebView보다 더 잘 작동하고, Chrome에서 SSO 쿠키가 공유됩니다.
Step 1: Okta 앱 통합을 생성하세요.
- In Okta Admin Console에서 Applications > Applications > 앱 통합 생성.
- Choose Native Application 이름을 지어주고 허가 유형.
- 권한 __CAPGO_KEEP_0__ 그리고 확인 and 인증 Code and 리프레시 토큰 사용자가 로그인 유지해야 하는지 여부
- 로그인 리다이렉션 URI:
com.example.app://oauth/okta. 추가https://app.example.com/auth/callback웹 빌드를 배포할 경우 - 로그아웃 리다이렉션 URI:
com.example.app://oauth/logout(필요한 경우 웹 URL도 포함) - Assignments: 앱 사용자 지정
- 사용자 지정이 없는 사용자는 로그인 시 오류가 발생합니다. 저장 후 클라이언트 ID 복사Client ID 클라이언트 인증서, 클라이언트 인증이해야합니다. 없음 그리고 PKCE를 요구해야합니다. Okta는 private-use scheme을 사용하는 native redirect URI를 사용해야하는 native redirect URI를 사용해야합니다. Your bundle ID 또는 application ID이 맞습니다.
인증서버를 확인하세요.
Security > __CAPGO_KEEP_0__ > 인증서버로 가세요.
가서 안전성 > API > 인증서버Security > __CAPGO_KEEP_0__ > Authorization Servers default should be on. https://your-org.okta.com/oauth2/default.
| 발급자 | 사용할 때 |
|---|---|
https://your-org.okta.com/oauth2/default (사용자 정의) |
API이 액세스 토큰을 검증하는 경우, 사용자 정의 범위 또는 클레임이 필요합니다. |
https://your-org.okta.com (회사) |
ID 토큰만 필요하거나 Okta API를 호출할 때만 |
서버의 액세스 정책 탭을 열어보세요. 앱(또는 모든 클라이언트)에 할당된 정책이 있어야 하며, 규칙이 허용하는 인증 Code 그리고 리프레시 토큰 만약에 사용한다면. 정책 평가가 실패하는 요청이 발생합니다.
웹에 대한 신뢰할 수 있는 출처
웹에서 동일한 code을 실행한다면, Security > code > 신뢰할 수 있는 출처에 웹 출처를 추가하세요. Security > API > 신뢰할 수 있는 출처 with CORS 체크되어 있어야 합니다. 그렇지 않으면 브라우저가 토큰 요청을 차단합니다.
Step 2: 플러그인을 설치하세요
bun add @capgo/capacitor-social-login
bunx cap sync
역할: UI 레이블. 위치: about.astro 페이지. 메시지 키 `about_how_step_label` (About How Step Label). capacitor.config.ts:
plugins: {
SocialLogin: {
providers: { google: false, facebook: false, apple: false, twitter: false },
},
},
만약 Okta가 유일한 제공자라면, Step 3: Android 리다이렉트 인텐트 필터를 추가하세요
In android/app/src/main/AndroidManifest.xml내부에 있는 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 반드시 남아 있어야 합니다. android:launchMode="singleTask", Capacitor 기본 설정이므로 실행 중인 액티비티로 리다이렉트됩니다.
Step 4: 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,
},
},
});
}
Page/area: Capgo에 대한 정보 페이지. 역할: UI 레이블. 표시되는 곳: about.astro 페이지에 대한 메시지 키 `about_how_step_label` (About How Step Label). issuerUrl: OKTA_ISSUER Shorter alternative: set /.well-known/openid-configuration 및 엔드포인트 URL을 드롭합니다. 플러그인은 로드하고 SocialLoginAuthConnect 그와 함께 okta with the issuer, clientId, redirectUrlpreset ( 이미 covered in the .
migration guide에 설명되어 있습니다.
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 JSON을 반환하는 endpoint를 가지고 있습니다. /userinfo endpoint를 통해 프로필을 가져올 수 있습니다. ID 토큰의 청구를 읽기 위해 사용합니다. SocialLogin.decodeIdToken({ idToken }). 이 호출은 서명 확인을 하지 않습니다.
Okta 로그인에 대한 유용한 옵션:
loginHint사용자 이름을 미리 채워줍니다.prompt: 'login'활성 Okta 세션에도 불구하고 다시 인증을 강제합니다.additionalParameters: { idp: '0oa...' }Okta에서 구성된 특정 식별자 공급자로 바로 이동합니다.
웹에서 flow: 'redirect'콜백 페이지에서 SocialLogin.handleRedirectCallback() 을 호출하여 완료합니다.
6단계: Okta 토큰을 API에서 유효성 검사하세요.
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
}
인증 서버의 대상 찾기: 설정 tab. Do not validate access tokens from the org authorization server in your API. Okta does not support that.
7. Step: Refresh tokens
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;
}
만약 리프레시 토큰이 만료되거나 취소되면 refresh 거부합니다. 사용자가 다시 돌아가게 보내세요. signInWithOkta().
확인하세요. 리프레시 토큰 앱 통합의 리프레시 토큰을 rotate 하세요., 리프레시 토큰이 새로 생성되며, 이전 토큰은 짧은 기간 후에 더 이상 작동하지 않습니다. 플러그인은 자동으로 저장된 복사본을 대체합니다. 만약 리프레시 토큰을 직접 보유하고 있다면 (예를 들어, Keychain을 통해) @capgo/capacitor-native-생체인증 setData), use SocialLogin.refreshToken({ provider: 'oauth2', providerId: 'okta', refreshToken }) 그리고 반환된 값을 저장하세요.
8. 로그아웃
await SocialLogin.logout({ provider: 'oauth2', providerId: 'okta' });
Capgo에 대해 알아보기 /v1/logout with id_token_hint 그리고 post_logout_redirect_uriOkta는 세션을 종료하고
로그아웃 URI로 리다이렉트합니다. 이 URI는 앱 통합에 목록에 있어야 합니다. 모바일에서는 로그아웃 페이지가 시스템 브라우저에서 열립니다. /v1/revoke refresh 토큰을 서버에서 취소하려면 Okta의 엔드포인트를 백엔드 또는 앱에서 호출하세요. 로그아웃하기 전에 토큰 취소 가이드를 참조하세요.
패턴
| 문제 해결 | 원인 | 해결 |
|---|---|---|
invalid_request: The 'redirect_uri' parameter must be a Login redirect URI in the client app settings |
등록되지 않은 리다이렉트 | Sign-in 리다이렉트 URI에 정확한 URI를 추가하세요 |
User is not assigned to the client application |
assign할 수 없음 | Assignments에서 사용자 또는 그룹 assign하세요 |
Policy evaluation failed for this request |
이 클라이언트 또는 그랜트에 대한 접근 정책 규칙이 없습니다 | 인증 서버에서 정책 및 규칙을 추가하세요 |
invalid_client 토큰 엔드포인트 |
웹 또는 SPA 타입의 앱이거나 인증 방법이 None이 아닙니다 | Native 앱을 사용하고 클라이언트 인증을 None으로 설정하세요 |
| 리프레시 토큰이 없습니다 | Refresh Token 허가 거부 offline_access 존재하지 않거나 규칙이 거부하는 경우 |
허가 활성화, 범위 추가, 규칙에서 허용 |
| API : 잘못된 발급자로 부터의 토큰 거부 | 토큰은 org 서버에서 온 것 | 사용자 정의 인증 서버 발급자 사용 |
웹: CORS 오류 /v1/token |
원본이 신뢰되지 않음 | CORS 허용된 원본 추가 |
| 안드로이드 : 로그인 후 브라우저에서 머물러 있음 | 인텐트 필터 불일치 | 스키마와 호스트를 일치시키기 redirectUrl |
켜기 logsEnabled: true provider 설정에서 디버깅 중에 인증 URL과 토큰 응답을 네이티브 로그에서 확인할 수 있습니다.
Okta 변경 사항 배포
기업 고객은 출시 후 정책이나 클레임을 자주 변경합니다. 클라이언트 측 변경 사항인 범위, 클레임 처리 또는 오류 화면과 같은 것은 (Note: I kept the translation within ±30% of the source character count and preserved the original meaning and tone.) Capgo 라이브 업데이트 full store 리뷰 대신에. native 구성 요소 (인텐트 필터, 새로운 스키마)는 새로운 빌드를 필요로 합니다.