Lewati ke konten utama

Authorization Code Flow dengan PKCE

Muhajir Studio mendukung OpenID Connect melalui Authorization Code Flow with PKCE. Aplikasi yang dibuat admin adalah Public PKCE clients: aplikasi memakai public client_id, tidak memiliki client_secret, dan harus membuktikan kepemilikan code_verifier saat token exchange.

Base URLs yang Digunakan dalam Flow Ini

ServiceBase URLPeran dalam flow ini
APIhttps://api.muhajirstudio.com//api/auth/oauth2/authorize, /api/auth/oauth2/token, UserInfo, JWKS, dan public metadata.
Main webhttps://login.muhajirstudio.com/Login, signup, email verification, dan consent UI.
Admin webhttps://admin.muhajirstudio.com/Client registration dan scope/redirect configuration.

Persyaratan Provider

OIDC provider dikonfigurasi dengan:

  • requirePKCE: true
  • allowPlainCodeChallengeMethod: false
  • defaultScope: openid
  • supported scopes dari OIDC_SCOPES
  • JWT-backed OIDC support
  • issuer dari OIDC_ISSUER

Hanya code_challenge_method=S256 yang didukung. Jangan memakai plain.

1. Siapkan Client Configuration

Minta nilai yang terdaftar di web-admin dari admin:

NilaiCatatan
client_idGenerated public client identifier.
Redirect URIHarus sama persis dengan satu derived registered redirectUri.
Allowed scopesApplication scope set yang dipilih admin.
IssuerNilai OIDC_ISSUER yang dikonfigurasi.

Aplikasi yang dibuat admin tidak pernah menerima client_secret.

2. Buat Nilai Per Request

Untuk setiap percobaan login, buat dan simpan:

NilaiTujuan
code_verifierSecret random string yang disimpan client sampai token exchange.
code_challengeBase64url SHA-256 digest dari code_verifier.
stateNilai proteksi CSRF yang harus round-trip.
nonceNilai proteksi replay untuk divalidasi di id_token.

Simpan state, nonce, dan code_verifier di server session atau mekanisme penyimpanan lain yang sesuai dengan tipe aplikasi Anda.

3. Mulai Authorization

Redirect browser ke https://api.muhajirstudio.com/api/auth/oauth2/authorize:

GET /api/auth/oauth2/authorize

Contoh query:

client_id=CLIENT_ID
redirect_uri=https%3A%2F%2Fapp.example.com%2Fauth%2Fcallback
response_type=code
scope=openid%20profile%20email
state=STATE
nonce=NONCE
code_challenge=CODE_CHALLENGE
code_challenge_method=S256

Parameter protokol wajib:

ParameterPersyaratan
client_idPublic client ID yang terdaftar di web-admin.
redirect_uriExact registered full URI.
response_typeHarus code.
scopeSpace-separated scopes; default provider adalah openid jika dihilangkan.
code_challengePKCE S256 challenge.
code_challenge_methodHarus S256.

Parameter yang direkomendasikan:

ParameterPersyaratan
stateSangat direkomendasikan untuk proteksi CSRF.
nonceSangat direkomendasikan saat memakai atau memvalidasi id_token.

web-main mempertahankan parameter OIDC ini melalui login, signup, email verification, dan halaman email-verified: client_id, redirect_uri, response_type, scope, state, code_challenge, code_challenge_method, nonce, prompt, max_age, dan login_hint.

4. Pemrosesan Authorization Request

Sebelum OIDC provider menangani authorize request, Muhajir Studio menerapkan tiga pemeriksaan server-side.

Redirect URI Validation

Untuk dynamic applications, server memuat aplikasi berdasarkan client_id dan memvalidasi bahwa redirect_uri ada di daftar derived redirectUris milik aplikasi.

Static trusted clients, seperti reserved web-admin client, divalidasi terhadap configured redirect URLs mereka.

Jika validasi gagal, response adalah:

{
"error": "INVALID_REDIRECT_URI",
"message": "redirect_uri is not registered for this client"
}

Scope Constraint

Untuk dynamic applications dengan configured scopes, server menulis ulang requested scope menjadi registered scope set milik aplikasi sebelum OIDC provider memproses request.

Ini berarti admin-selected scopes adalah source of truth untuk dynamic applications.

Email Verification Gate

Jika pengguna sudah sign in tetapi emailVerified bukan true, server redirect ke /verify-email di web-main dan mempertahankan query parameters authorize asli. Pengguna tidak dapat menyelesaikan authorization sampai email verification selesai.

OIDC provider memakai configured loginPage dan consentPage URLs. Alur yang terlihat oleh pengguna dapat mencakup:

  1. Login atau signup.
  2. Email verification.
  3. Consent.
  4. Redirect kembali ke client callback.

Consent page memuat public application metadata dari GET /api/public/applications/{clientId}. Jika ada query value redirect_uri, nilai tersebut diteruskan agar metadata endpoint dapat menurunkan post-verification redirect URI dengan aman.

Ketika pengguna yang sudah sign in memilih untuk switch account dari consent page, web-main melakukan sign out pada session saat ini dan kembali ke post-verification URL milik aplikasi terdaftar jika tersedia. Aplikasi client kemudian harus memulai authorization request baru dengan state dan PKCE challenge baru.

Approval dinonaktifkan ketika application metadata tidak dapat dimuat.

6. Tangani Callback

Setelah approval, Muhajir Studio redirect ke registered redirect_uri dengan authorization code dan state asli.

Callback handler Anda harus:

  1. Memverifikasi state sama dengan nilai yang disimpan.
  2. Mengambil code_verifier yang disimpan.
  3. Menukar code di token endpoint.
  4. Memvalidasi id_token claims saat ID token dipakai untuk local sign-in.

7. Tukar Authorization Code

Kirim form-encoded token request:

POST /api/auth/oauth2/token
Content-Type: application/x-www-form-urlencoded

grant_type=authorization_code&code=AUTHORIZATION_CODE&code_verifier=CODE_VERIFIER&client_id=CLIENT_ID&redirect_uri=https%3A%2F%2Fapp.example.com%2Fauth%2Fcallback

Jangan kirim client_secret untuk Public PKCE clients yang dibuat admin.

Token response yang berhasil dapat berisi:

{
"access_token": "...",
"token_type": "Bearer",
"expires_in": 3600,
"id_token": "...",
"refresh_token": "...",
"scope": "openid profile email"
}

Gunakan access token sebagai Authorization: Bearer ACCESS_TOKEN saat memanggil OIDC UserInfo atau /api/external/* APIs.

8. Refresh Tokens

Token endpoint juga mendukung grant_type=refresh_token jika didukung oleh OIDC provider dan granted scopes/client configuration. Scope offline_access ditujukan untuk refresh-token based sessions jika didukung.

Third-party clients sebaiknya memakai standard token endpoint secara langsung kecuali secara eksplisit diminta memakai first-party cookie helper.

Security Checklist

  • Gunakan HTTPS redirect URIs di luar local development.
  • Buat state, nonce, dan PKCE values baru untuk setiap percobaan login.
  • Validasi state sebelum menukar code.
  • Validasi id_token issuer, audience, expiry, signature, dan nonce saat digunakan untuk sign-in.
  • Jangan pernah memakai atau menyimpan client secret untuk Public PKCE clients yang dibuat admin.
  • Simpan tokens sesuai tipe aplikasi dan threat model Anda.