İçeriğe atla

OpenID Connect Akış Diyagramı: Yetkilendirme Kodu Akışı, ID Token'lar ve Discovery

OpenID Connect, OAuth 2.0'a oturum açmayı nasıl ekler: PKCE'li yetkilendirme kodu akışı, ID token ve doğrulaması, discovery, JWKS, UserInfo ve oturum kapatma.

· Kurucu ve geliştirici

Yayımlandı:

Bir kullanıcı, bir tarayıcı, bir relying party ve bir OpenID sağlayıcısı içeren sıralama diyagramı. Numaralı on üç mesaj yönlendirmeyi, girişi, kod takasını ve token yanıtını kapsar; bir critical parçası ID token'ı doğrular, bir opt parçası UserInfo'yu çağırır.

Bir mobil uygulama, kullanıcının bir kimlik sağlayıcıyla oturum açmasını sağlar ve access token'ı backend'inize iletir; backend de sağlayıcının profil uç noktasını çağırır, bir e-posta adresi alır ve bir oturum oluşturur. Bütün testler geçer. Ne var ki bu kurgu, kullanıcının aynı sağlayıcıyla oturum açtığı başka herhangi bir uygulamanın da kendi access token'ıyla uygulamanıza o kullanıcı olarak giriş yapmasına izin verir; çünkü token'ın hangi uygulamaya verildiğini hiçbir şey kontrol etmez.

OpenID Connect (OIDC) bu açığı kapatır. OAuth 2.0'a bir ID token ekler: sağlayıcının, kullanıcının kim olduğunu, token'ın hangi uygulama için olduğunu ve kullanıcının ne zaman oturum açtığını beyan ettiği imzalı bir JWT.

Bu yazı, PKCE'li yetkilendirme kodu akışını (authorization code flow) bir sıralama diyagramı olarak çiziyor ve OIDC'nin neler eklediğini ele alıyor: openid scope'u, nonce, ID token doğrulama, discovery, anahtar rotasyonu, UserInfo ve oturum kapatma.

OAuth 2.0 ile OpenID Connect karşılaştırması

OAuth 2.0 erişimle ilgilidir: kullanıcı adına bir API'yi çağırmak için bir token. OpenID Connect ise kimlikle ilgilidir: kimin oturum açtığı.

OAuth 2.0 OpenID Connect
Yanıtladığı soru Bu uygulama bu API'yi çağırabilir mi? Kullanıcı kim ve ne zaman oturum açtı?
Token Access token ID token
Token kimin için API Uygulamanız
Token biçimi Tanımlanmamış: opak ya da JWT İmzalı bir JWT
Nasıl istenir API'nin tanımladığı scope'lar scope içinde openid bulunur
Tanımladıkları Grant türleri ve uç noktalar Claim'ler, UserInfo, discovery, oturum kapatma

Ağ trafiğine bakıldığında bir OIDC girişi, scope'unda openid bulunan bir OAuth yetkilendirme isteğidir ve token yanıtı, access token'ın yanında bir id_token da taşır. OAuth 2.0 akış diyagramı işin OAuth tarafını ayrıntılı olarak ele alıyor.

Adım adım akış

OpenID Connect Core 1.0 uygulamanızı relying party (RP), yetkilendirme sunucusunu ise OpenID sağlayıcısı (OpenID provider, OP) olarak adlandırır. Tarayıcıdan geçen her şey, yani ön kanal (front channel), URL'lere, tarayıcı geçmişine ve loglara sızabilir; backend'inizden sağlayıcıya yapılan çağrılar, yani arka kanal (back channel), sızamaz. Numaralar diyagramla aynıdır.

  1. Başlangıç (1–3). Kullanıcı “Giriş yap” düğmesine tıklar. Uygulamanız oturuma yeni bir state, nonce ve PKCE code_verifier kaydeder ve tarayıcıyı sağlayıcıya yönlendirir.
  2. Kimlik doğrulama isteği (4). Tarayıcı yönlendirmeyi izler:
GET /authorize?response_type=code
    &client_id=orders-web
    &redirect_uri=https%3A%2F%2Fapp.example.com%2Fcallback
    &scope=openid%20profile%20email
    &state=7fJq2LbX9aQe
    &nonce=n-0S6_WzA2Mj
    &code_challenge=E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM
    &code_challenge_method=S256 HTTP/1.1
Host: op.example.com
  1. Giriş ve onay (5). Sağlayıcı kullanıcının kimliğini doğrular (parola, geçiş anahtarı, MFA ya da mevcut bir oturumla) ve onay ister. Uygulamanız kimlik bilgilerini hiçbir zaman görmez.
  2. Kodun dönüşü (6–7). Sağlayıcı, kısa ömürlü bir code ve aynı state ile kayıtlı redirect_uri adresine yönlendirir; uygulamanız bu değeri oturumdakiyle karşılaştırır.
  3. Token isteği (8–9). Backend'iniz code, redirect_uri ve code_verifier değerlerini istemci kimlik bilgileriyle birlikte POST eder. Sağlayıcı verifier'ı challenge ile karşılaştırır ve bir id_token, bir access_token ve çoğu zaman bir refresh_token döndürür.
  4. Doğrulama (10). Uygulamanız ID token'ı doğrular; imzalama anahtarlarını yalnızca token'ın işaret ettiği anahtar önbellekte yoksa çeker.
  5. UserInfo (11–12), isteğe bağlı. Yalnızca ID token'da ihtiyaç duyduğunuz claim'ler eksikse.
  6. Oturum (13). Uygulamanız kendi oturumunu oluşturur ve bir çerez ayarlar.

state, nonce ve PKCE neye karşı korur

Değer Taşındığı yer Kontrol eden Engellediği
state 4. adım ve geri yönlendirme Uygulamanız Kullanıcının hiç başlatmadığı bir giriş yanıtı (CSRF)
nonce 4. adım, ardından ID token'ın içi Uygulamanız ID token'ın tekrar oynatılması (replay) ve gizli istemcilerde yetkilendirme kodu enjeksiyonu
code_verifier 4. adımda SHA-256 özeti, 8. adımda kendisi Sağlayıcı Çalınan bir kodun kullanılması

OAuth için güncel en iyi güvenlik uygulamalarını tanımlayan RFC 9700, bazı durumlarda birinin diğerinin yerini tutmasına izin verir; ama her biri yalnızca bir rastgele değere mal olur, bu yüzden üçünü de gönderin. Tek sayfalı uygulamalar ve mobil uygulamalar gibi açık istemciler (public client), PKCE'yi (RFC 7636) S256 ile kullanmak zorundadır.

ID token'ın içinde

Çözümlenmiş hâliyle, 9. adımda gelen ID token:

{
  "iss": "https://op.example.com",
  "sub": "248289761001",
  "aud": "orders-web",
  "nonce": "n-0S6_WzA2Mj",
  "iat": 1793736400,
  "exp": 1793740000,
  "auth_time": 1793736390
}
Claim Anlamı Uygulamanız
iss Issuer (yayıncı), bir https URL'si Discovery'den alınan issuer ile birebir aynı olmalı
sub Kullanıcı kimliği; aynı issuer içinde asla başkasına atanmaz, en fazla 255 ASCII karakter Hesap anahtarı olarak iss ile sub ikilisini kullanır
aud Audience (hedef kitle), bir string ya da dizi İçinde kendi client_id değerini bulmalı
exp, iat Unix saniyesi cinsinden son geçerlilik ve düzenlenme zamanı Süresi dolmuş ya da çok eski token'ları reddeder
nonce 4. adımda gönderilen değer Oturumdakiyle eşleşmeli
auth_time Kullanıcının gerçekte kimlik doğruladığı an max_age gönderdiğinizde bunu kontrol eder
acr, amr Güvence düzeyi ve yöntemler, örneğin pwd ya da mfa Hassas işlemlerden önce bunları kontrol eder

Core bunu açıkça belirtir: bir kullanıcıyı yalnızca iss ile sub ikilisi tanımlar; e-posta adresleri değişir ve başkasına yeniden atanabilir.

ID token'ı doğrulamak

Core'un 3.1.3.7 numaralı bölümü kuralları sıralar:

  1. Algoritmayı sabitleyin (varsayılan RS256); alg başlığına güvenmeyin ve none değerini asla kabul etmeyin.
  2. İmzayı doğrulayın: kid ile belirtilen JWKS anahtarını kullanın. Token doğrudan token uç noktasından geldiği için Core, kod akışındaki bir istemcinin bunun yerine TLS'e güvenmesine izin verir; ama doğrulamanın maliyeti düşüktür.
  3. iss değerini kontrol edin: discovery'den alınan issuer ile karakteri karakterine aynı olmalı.
  4. aud değerini kontrol edin: içinde client_id değeriniz bulunmalı; güvenmediğiniz audience'ları reddedin.
  5. exp ve iat değerlerini kontrol edin; birkaç saniyeden birkaç dakikaya kadar saat kaymasına izin verin.
  6. nonce değerini kontrol edin: oturumdakiyle eşleşmeli; ardından onu silin.
  7. auth_time ve acr değerlerini kontrol edin; tabii onları istediyseniz.

Oturumu ancak bundan sonra oluşturun. Node.js'te jose kütüphanesiyle:

import { createRemoteJWKSet, jwtVerify } from 'jose'

// issuer and jwks_uri come from the discovery document.
// The key set is cached; an unknown kid triggers a refetch
// (at most once every 30 seconds by default).
const JWKS = createRemoteJWKSet(new URL(oidc.jwks_uri))

const { payload } = await jwtVerify(tokens.id_token, JWKS, {
  issuer: oidc.issuer,     // exact match
  audience: CLIENT_ID,     // must appear in aud
  algorithms: ['RS256'],   // never trust the header alone
  clockTolerance: 60,      // seconds of clock skew
  maxTokenAge: 600,        // rejects an old iat
})
if (payload.nonce !== session.nonce) throw new Error('nonce mismatch')

Discovery ve anahtar rotasyonu

OpenID Connect Discovery 1.0, bir sağlayıcının ayarlarını, issuer URL'sinin sonuna /.well-known/openid-configuration eklenerek ulaşılan tek bir JSON belgesinde toplar. Bu yazının yazıldığı tarihte (Kasım 2026) Google'ınki, bu akışın kullandığı alanlara indirgenmiş hâliyle şöyle:

{
  "issuer": "https://accounts.google.com",
  "authorization_endpoint": "https://accounts.google.com/o/oauth2/v2/auth",
  "token_endpoint": "https://oauth2.googleapis.com/token",
  "userinfo_endpoint": "https://openidconnect.googleapis.com/v1/userinfo",
  "jwks_uri": "https://www.googleapis.com/oauth2/v3/certs",
  "id_token_signing_alg_values_supported": ["RS256"],
  "code_challenge_methods_supported": ["plain", "S256"]
}

issuer, belgeyi çektiğiniz issuer URL'siyle ve her ID token'ın iss değeriyle birebir aynı olmalıdır. Beklenen issuer'ı kendiniz yapılandırın; onu asla doğrulamadığınız bir token'dan almayın.

Anahtarlar jwks_uri üzerinden döner: Sağlayıcı yeni bir anahtar ekler, onunla imzalar ve eskisini bir süre daha yayında tutar (Core, bölüm 10.1.1). Anahtar kümesini önbelleğe alın, Cache-Control başlığına uyun, tanımadığınız bir kid geldiğinde kümeyi yeniden çekin ve bu yeniden çekmelere hız sınırı koyun. JWT kimlik doğrulama akış diyagramı aynı mekanizmayı access token'lar için ele alıyor.

UserInfo

UserInfo'yu access token ile çağırdığınızda, verilen scope'lara (profile, email, address, phone) ait claim'leri döndürür. Yanıtında her zaman sub bulunur; bu değer ID token'daki sub ile birebir eşleşmelidir, aksi hâlde yanıtı atarsınız.

Oturum kapatma seçenekleri

Oturum kapatmayı, nihai (final) statüdeki üç OpenID spesifikasyonu ele alır:

Spesifikasyon Nasıl çalışır Dikkat edilmesi gereken
RP-Initiated Logout 1.0 Uygulamanız id_token_hint ile sağlayıcının end_session_endpoint adresine yönlendirir Uygulamanız kendi oturumunu da sonlandırmalıdır
Front-Channel Logout 1.0 Sağlayıcı her uygulamanın logout URL'sini bir iframe içinde yükler Üçüncü taraf çerezlerin engellenmesi bunu bozabilir
Back-Channel Logout 1.0 Sağlayıcı her uygulamaya imzalı bir logout token'ı POST eder Uygulamanız oturumu sunucu tarafında bulup sonlandırmalıdır

Core ayrıca, ID token'daki exp değerinin oturum süresiyle ilgisi olmadığını da belirtir.

İncelemelerde karşılaşılan hatalar

  • Kimlik kanıtı olarak access token. Yazının başındaki senaryo. Kullanıcıların oturumunu yalnızca backend'inizin token uç noktasından aldığı ve doğruladığı bir ID token ile açın.
  • aud ya da nonce kontrolünü atlamak. Aynı sağlayıcıya kayıtlı her uygulama, aynı iss değerine sahip ve geçerli şekilde imzalanmış ID token'lar alır; bir token'ın size verildiğini yalnızca aud söyler ve onu bu girişe yalnızca nonce bağlar.
  • Implicit akış. response_type=id_token token, token'ları URL fragment'ına koyar; RFC 9700, istemcilerin yetkilendirme yanıtında access token döndüren yanıt türlerini kullanmaması gerektiğini söyler. Tek sayfalı uygulamalarda da PKCE ile birlikte code kullanın.
  • API'lere gönderilen ID token'lar. API'ler yalnızca kendileri için verilmiş access token'ları kabul etmelidir; API gateway mimari diyagramı bu kontrolün genellikle nerede yapıldığını gösteriyor.

OpenID Connect akış diyagramı

Bir kullanıcı, bir tarayıcı, bir relying party ve bir OpenID sağlayıcısı içeren sıralama diyagramı. Numaralı on üç mesaj yönlendirmeyi, girişi, kod takasını ve token yanıtını kapsar; bir critical parçası ID token'ı doğrular, bir opt parçası UserInfo'yu çağırır.

16 bileşen · 13 bağlantı

Archboard'da aç
Diyagram içeriği
  • User
  • Browser
  • Relying party (your app)
  • OpenID provider
  • all checks must pass
  • claims missing from the ID token
  • ID token: for your app (aud = client_id)
  • Access token: for UserInfo and APIs
  • 1. Click Sign in
  • 2. GET /login
  • 3. 302 to the provider's /authorize
  • 4. GET /authorize: scope=openid, state, nonce, code_challenge
  • 5. Log in (password, passkey, MFA) and consent
  • 6. 302 to redirect_uri with code, state
  • 7. GET /callback?code&state
  • 8. POST /token: code, code_verifier, client auth
  • 9. id_token, access_token
  • 10. GET jwks_uri (when kid is not cached)
  • 11. GET /userinfo, Bearer access_token
  • 12. Claims; sub must match the ID token
  • 13. 302 to the app, Set-Cookie: session
PKCE'li OpenID Connect yetkilendirme kodu akışı. Uygulamanız tarayıcıyı scope=openid, state, nonce ve bir code challenge ile sağlayıcıya gönderir, kodu arka kanal üzerinden takas eder ve oturum oluşturmadan önce ID token'ı doğrular.

Nasıl okunur:

  • Dört katılımcı: kullanıcı, tarayıcı, uygulamanız (relying party) ve OpenID sağlayıcısı. Zaman yukarıdan aşağıya akar.
  • Renkler kanalı gösterir: mavi tarayıcı üzerinden geçenleri, camgöbeği backend'inizden sağlayıcıya gidenleri, mor da kullanıcının eylemlerini. Kesikli oklar yanıtlar ve yönlendirmelerdir.
  • 3. ve 4. adımlar scope=openid, state, nonce ve PKCE challenge'ını taşır; 8. adım ise verifier'ı taşır.
  • critical parçası, anahtarın çekilmesini ve oturum oluşmadan önce geçilmesi gereken kontrolleri içerir. opt parçası UserInfo çağrısıdır.
  • Sağdaki sütun discovery alanlarını adımlarla eşleştirir, PKCE parametrelerini listeler, bir ID token'ı çözümlenmiş olarak gösterir ve hangi token'ın kimin için olduğunu belirtir.

OpenID Connect diyagramlarını net çizmek

  • Tarayıcıya kendi yaşam çizgisini verin. Ön kanal ile arka kanal arasındaki ayrım, bu akışın güvenlik hikâyesinin ta kendisidir.
  • Kontrol edilen parametreleri okların üzerine yazın: state, nonce, code_challenge, code_verifier.
  • Doğrulamayı açık açık yazın. “Token'ı doğrula” incelenemez; “imza, iss, aud, exp, iat, nonce” incelenebilir.
  • Hangi token'ın nereye gittiğini belirtin, audience'ıyla birlikte. Pek çok OIDC hatası, yanlış tarafa gönderilmiş bir token'dır.
  • Diyagram başına tek akış. Girişi, token yenilemeyi ve oturum kapatmayı ayrı ayrı çizin; kimlikler ve token'lar için yer tutucu değerler kullanın.

Sıralama diyagramı örneği gösterimi ele alıyor; SAML SSO akış diyagramı ise kurumsal müşterilerin hâlâ istediği XML tabanlı protokolü gösteriyor.

Archboard'da oluşturun

  1. Google ya da GitHub ile giriş yapın ve bir diyagram oluşturun.
  2. Sequence paketinden kullanıcı için bir Aktör ve eşit yükseklikte üç Yaşam çizgisi düğümü ekleyin: Browser, Relying party (your app) ve OpenID provider.
  3. 13 mesajı yukarıdan aşağıya düz ve numaralı kenarlar olarak çizin. Yanıtları kesikli yapın; ön kanal ile arka kanalı farklı renklere boyayın.
  4. Sequence paketinden, anahtar çekme adımını ve kontrolleri çevreleyen critical operatörlü bir Parça ve UserInfo çağrısını çevreleyen opt operatörlü ikinci bir Parça ekleyin.
  5. Oturum değerleri ve kontroller için relying party'nin yanına Temel paketinden Metin ekleyin; bir de renk açıklaması ekleyin.
  6. Discovery, PKCE ve çözümlenmiş bir ID token için Temel paketinden bir Markdown bloğu; ID token ve access token için de Güvenlik paketinden iki Jeton düğümü ekleyin.

Örnek 9 diyagram düğümü kullanıyor ve Free planın sınırları içinde kalıyor. AI ajanınız da bunu MCP üzerinden çizebilir.

SSS

OAuth 2.0 ile OpenID Connect arasındaki fark nedir? OAuth 2.0 bir uygulamaya, bir API'yi çağırması için access token verir. OpenID Connect bunun üzerine oturum açmayı ekler: openid scope'u, kullanıcının kim olduğunu söyleyen bir ID token ve standart discovery ile UserInfo uç noktaları.

ID token ile access token aynı şey mi? Hayır. ID token, uygulamanız için düzenlenen ve kimin oturum açtığını söyleyen imzalı bir JWT'dir. Access token ise UserInfo dahil API'ler içindir. ID token'ları asla API'lere göndermeyin, access token'ları da asla giriş kanıtı olarak kabul etmeyin.

Zaten nonce gönderiyorsam PKCE'ye ihtiyacım var mı? İkisini de kullanın. RFC 9700, açık istemciler için PKCE'yi zorunlu tutar. Gizli bir istemci ek önlemler alarak nonce'a güvenebilir; ama PKCE çalınan bir kodun kullanılmasını engellerken nonce, enjekte edilmiş bir kodu ancak token yanıtından sonra fark eder.

Bir ID token nasıl doğrulanır? İmzayı kid değeriyle eşleşen JWKS anahtarıyla doğrulayın; ardından iss değerinin issuer'a eşit olduğunu, aud değerinin client ID'nizi içerdiğini, exp süresinin geçmediğini, iat değerinin yakın tarihli olduğunu ve nonce değerinin oturumla eşleştiğini kontrol edin.

/.well-known/openid-configuration nedir? OpenID Connect discovery belgesidir. Bir sağlayıcının issuer'ını, uç noktalarını, algoritmalarını ve jwks_uri değerini listeler; böylece uygulamanız kendini tek bir URL'den yapılandırabilir.

Ücretsiz başlayın — tek kullanıcı, kredi kartı gerekmez.

İlgili yazılar

← Blog'a dön

Bir dakikada canvas açın

Google veya GitHub ile giriş yapın. Tek koltuk ücretsiz; ekip katılınca planı yükseltin.