OAuth 2.0 & OpenID Connect
Atlantic ID, OAuth 2.0 ve OpenID Connect (OIDC) standartlarına tam uyumlu bir Identity Provider'dır. Bu sayfa protokol detaylarını, flow'ları ve best practices'leri açıklar.
OAuth 2.0 vs OpenID Connect
OAuth 2.0
- Amaç: Authorization (yetkilendirme)
- Ne sağlar: Access token → API'lere erişim
- Örnek: "MyApp'in Gmail'ime erişmesine izin veriyorum"
OpenID Connect (OIDC)
- Amaç: Authentication (kimlik doğrulama)
- Ne sağlar: ID token → Kullanıcının kimliği
- Örnek: "Gmail hesabımla MyApp'e giriş yapıyorum"
Atlantic ID her ikisini de destekler.
openidscope'u ile OIDC aktif olur.
Authorization Code Flow
Atlantic ID'nin kullandığı tek grant type budur. En güvenli OAuth flow'dur.
Flow Diyagramı
┌──────────┐ ┌──────────────┐
│ │ │ │
│ Client │ │ Atlantic ID │
│ App │ │ │
│ │ │ │
└────┬─────┘ └──────┬───────┘
│ │
│ 1. GET /oauth/authorize │
│ + client_id, scope, redirect_uri │
│ + code_challenge (PKCE) │
│ ─────────────────────────────────────────────────▶
│ │
│ 2. User Login & Consent │
│ (Atlantic ID'de) │
│ │
│ 3. 302 Redirect │
│ Location: redirect_uri?code=XXX&state=YYY │
│◀─────────────────────────────────────────────────│
│ │
│ 4. POST /oauth/token │
│ + code, code_verifier │
│ ─────────────────────────────────────────────────▶
│ │
│ 5. Response: │
│ { access_token, id_token, refresh_token } │
│◀─────────────────────────────────────────────────│
│ │
│ 6. GET /oauth/userinfo │
│ Authorization: Bearer {access_token} │
│ ─────────────────────────────────────────────────▶
│ │
│ 7. Response: { sub, name, email, ... } │
│◀─────────────────────────────────────────────────│
Discovery Endpoint
Atlantic ID, OpenID Connect Discovery standardını destekler. Tüm endpoint'leri ve konfigürasyonu otomatik keşfedebilirsiniz.
Endpoint
GET https://id.codeatlantis.com/.well-known/openid-configuration
Response
{
"issuer": "https://id.codeatlantis.com",
"authorization_endpoint": "https://id.codeatlantis.com/oauth/authorize",
"token_endpoint": "https://id.codeatlantis.com/oauth/token",
"userinfo_endpoint": "https://id.codeatlantis.com/oauth/userinfo",
"jwks_uri": "https://id.codeatlantis.com/oauth/jwks",
"registration_endpoint": "https://id.codeatlantis.com/oauth/register",
"revocation_endpoint": "https://id.codeatlantis.com/oauth/revoke",
"end_session_endpoint": "https://id.codeatlantis.com/oauth/logout",
"scopes_supported": [
"openid", "profile", "email", "phone", "offline_access"
],
"response_types_supported": ["code"],
"response_modes_supported": ["query", "fragment"],
"grant_types_supported": ["authorization_code", "refresh_token"],
"subject_types_supported": ["public"],
"id_token_signing_alg_values_supported": ["RS256"],
"token_endpoint_auth_methods_supported": [
"none",
"client_secret_basic",
"client_secret_post"
],
"code_challenge_methods_supported": ["S256", "plain"],
"claims_supported": [
"sub", "name", "email", "email_verified",
"phone_number", "picture", "updated_at",
"iss", "aud", "exp", "iat", "auth_time", "nonce", "acr", "amr"
]
}
Authorization Request
Endpoint
GET https://id.codeatlantis.com/oauth/authorize
Parametreler
| Parametre | Tip | Zorunlu | Açıklama |
|---|---|---|---|
client_id |
string | ✅ | Developer Console'dan alınan client ID |
response_type |
string | ✅ | Daima code |
scope |
string | ✅ | Boşlukla ayrılmış scope listesi. En az openid |
redirect_uri |
string | ✅ | Kayıtlı redirect URI'lerden biri |
state |
string | 📝 Önerilen | CSRF koruması (rastgele string) |
nonce |
string | 📝 Önerilen | ID token replay koruması (rastgele string) |
code_challenge |
string | ✅ Public | PKCE code challenge (S256 hash) |
code_challenge_method |
string | ✅ Public | S256 veya plain (S256 önerilir) |
prompt |
string | ❌ | Davranış kontrolü (detaylar aşağıda) |
max_age |
integer | ❌ | Son auth'dan beri geçen max saniye |
ui_locales |
string | ❌ | UI dili (tr, en) |
acr_values |
string | ❌ | İstenen güvenlik seviyesi |
Prompt Values
| Değer | Davranış |
|---|---|
none |
Hiç prompt gösterme, session varsa sessizce devam et |
login |
Kullanıcıyı zorunlu olarak tekrar login yap |
consent |
Onay ekranını zorunlu göster |
select_account |
Hesap seçimi ekranı göster (multi-account) |
Örnek İstek
GET /oauth/authorize?
client_id=cli_abc123&
response_type=code&
scope=openid%20profile%20email%20phone&
redirect_uri=https://myapp.com/callback&
state=xyz789&
nonce=abc123&
code_challenge=E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM&
code_challenge_method=S256&
prompt=consent&
ui_locales=tr HTTP/1.1
Host: id.codeatlantis.com
Success Response
Kullanıcı giriş yaptıktan sonra redirect_uri'ye 302 redirect:
HTTP/1.1 302 Found
Location: https://myapp.com/callback?code=AQCxxx...xxx&state=xyz789
Error Response
HTTP/1.1 302 Found
Location: https://myapp.com/callback?
error=access_denied&
error_description=User%20denied%20access&
state=xyz789
Error Codes
| Error | Açıklama |
|---|---|
invalid_request |
Eksik veya hatalı parametreler |
unauthorized_client |
Client ID geçersiz |
access_denied |
Kullanıcı izni reddet |
unsupported_response_type |
response_type desteklenmiyor |
invalid_scope |
Scope geçersiz veya izin yok |
server_error |
Sunucu hatası |
temporarily_unavailable |
Servis geçici olarak kullanılamıyor |
Token Exchange
Endpoint
POST https://id.codeatlantis.com/oauth/token
Content-Type
application/x-www-form-urlencoded
Grant Type: Authorization Code
Request Parameters
| Parametre | Tip | Zorunlu | Açıklama |
|---|---|---|---|
grant_type |
string | ✅ | authorization_code |
code |
string | ✅ | Authorization code |
redirect_uri |
string | ✅ | Authorize request'tekiyle aynı olmalı |
client_id |
string | ✅ | Client ID |
client_secret |
string | 🔒 Conf | Confidential client'lar için |
code_verifier |
string | ✅ PKCE | PKCE code verifier |
Request Example
With Client Secret (Confidential):
POST /oauth/token HTTP/1.1
Host: id.codeatlantis.com
Content-Type: application/x-www-form-urlencoded
Authorization: Basic Y2xpX2FiYzEyMzpzZWNfZGVmNDU2
grant_type=authorization_code&
code=AQCxxx...xxx&
redirect_uri=https://myapp.com/callback&
code_verifier=dBjftJeZ4CVP-mB92K27uhbUbP1E_4jY3F_EA2ZXCUE
Public Client:
POST /oauth/token HTTP/1.1
Host: id.codeatlantis.com
Content-Type: application/x-www-form-urlencoded
grant_type=authorization_code&
code=AQCxxx...xxx&
client_id=cli_abc123&
redirect_uri=https://myapp.com/callback&
code_verifier=dBjftJeZ4CVP-mB92K27uhbUbP1E_4jY3F_EA2ZXCUE
Response
{
"access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...",
"token_type": "Bearer",
"expires_in": 900,
"id_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...",
"refresh_token": "RT_xxxxxxxxxxxxxxxxxxxxxxxx",
"scope": "openid profile email phone"
}
| Alan | Açıklama |
|---|---|
access_token |
API endpoint'lerine erişim için JWT |
token_type |
Her zaman "Bearer" |
expires_in |
Access token'ın geçerlilik süresi (saniye) |
id_token |
Kullanıcı kimlik bilgilerini içeren JWT |
refresh_token |
Token yenileme için (offline_access scope gerekli) |
scope |
Verilen scope'lar |
Refresh Token Flow
Access token süresi dolduğunda yeni token almak için:
Request
POST /oauth/token HTTP/1.1
Host: id.codeatlantis.com
Content-Type: application/x-www-form-urlencoded
Authorization: Basic Y2xpX2FiYzEyMzpzZWNfZGVmNDU2
grant_type=refresh_token&
refresh_token=RT_xxxxxxxxxxxxxxxxxxxxxxxx&
scope=openid%20profile%20email
Not:
scopeparametresi opsiyoneldir. Verilirse orijinal scope'tan daha dar olmalıdır.
Response
{
"access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...",
"token_type": "Bearer",
"expires_in": 900,
"id_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...",
"refresh_token": "RT_yyyyyyyyyyyyyyyyyyyyyyyy",
"scope": "openid profile email"
}
Refresh Token Rotation: Güvenlik için her refresh'te yeni bir refresh token döner. Eski token geçersiz olur.
UserInfo Endpoint
Endpoint
GET https://id.codeatlantis.com/oauth/userinfo
Authentication
Authorization: Bearer {access_token}
Request Example
GET /oauth/userinfo HTTP/1.1
Host: id.codeatlantis.com
Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...
Response
{
"sub": "550e8400-e29b-41d4-a716-446655440000",
"name": "Görkem Yılmaz",
"email": "gorkem@codeatlantis.com",
"email_verified": true,
"phone_number": "+905001234567",
"picture": "https://id.codeatlantis.com/avatar/550e8400.jpg",
"updated_at": 1735686000
}
Response içeriği scope'a bağlıdır. Detaylar için Scopes & Claims sayfasına bakın.
Client Authentication Methods
Atlantic ID üç farklı client authentication yöntemini destekler:
1. None (Public Clients)
Mobile ve SPA uygulamalar için. Client secret yok.
POST /oauth/token HTTP/1.1
Content-Type: application/x-www-form-urlencoded
grant_type=authorization_code&
client_id=cli_abc123&
code=xxx&
code_verifier=yyy
2. Client Secret Basic (Confidential)
HTTP Basic Auth ile:
POST /oauth/token HTTP/1.1
Authorization: Basic Y2xpX2FiYzEyMzpzZWNfZGVmNDU2
Content-Type: application/x-www-form-urlencoded
grant_type=authorization_code&
code=xxx&
code_verifier=yyy
Basic Auth:
base64(client_id:client_secret)
3. Client Secret Post (Confidential)
Body'de gönder:
POST /oauth/token HTTP/1.1
Content-Type: application/x-www-form-urlencoded
grant_type=authorization_code&
client_id=cli_abc123&
client_secret=sec_def456&
code=xxx&
code_verifier=yyy
Logout
Front-Channel Logout (Redirect)
GET https://id.codeatlantis.com/oauth/logout?
id_token_hint={id_token}&
post_logout_redirect_uri=https://myapp.com/goodbye
Kullanıcıyı Atlantic ID'den logout yapar ve post_logout_redirect_uri'ye yönlendirir.
Back-Channel Logout (Token Revocation)
POST /oauth/revoke HTTP/1.1
Host: id.codeatlantis.com
Content-Type: application/x-www-form-urlencoded
Authorization: Basic Y2xpX2FiYzEyMzpzZWNfZGVmNDU2
token=RT_xxxxxxxxxxxxxxxxxxxxxxxx&
token_type_hint=refresh_token
Detaylar için Logout sayfasına bakın.
Best Practices
✅ Yapılması Gerekenler
- HTTPS Kullan: Production'da her zaman HTTPS
- State Kullan: CSRF koruması için state parametresi zorunlu
- PKCE Kullan: Public client'larda zorunlu, confidential'da önerilen
- Nonce Kullan: ID token replay attack koruması
- Token Doğrula: ID token'ı her zaman backend'de doğrula
- Kısa TTL: Access token'ları kısa ömürlü tut (15 dk)
- Scope Minimize: Sadece ihtiyaç duyduğunuz scope'ları iste
❌ Yapılmaması Gerekenler
- Implicit Flow Kullanma: Deprecated ve güvensiz
- Secret'ı Frontend'de Sakla: Client secret asla frontend'de olmamalı
- Token'ı URL'de Gönder: Query param olarak göndermeyin (log'lara düşer)
- LocalStorage'da Token: XSS riski (httpOnly cookie kullanın)
- State Atlama: CSRF saldırısına açık
Troubleshooting
redirect_uri_mismatch
Sorun: Redirect URI eşleşmiyor
Çözüm:
- Console'dan registered URI'leri kontrol edin
- Protocol (http/https) tam eşleşmeli
- Trailing slash dikkat (
/callbackvs/callback/) - Port numarası dahil (
http://localhost:3000)
invalid_grant
Sorun: Authorization code geçersiz
Çözüm:
- Code'lar tek kullanımlık (reuse edilemez)
- 5 dakika içinde kullanılmalı
- Doğru redirect_uri ile exchange edilmeli
unsupported_grant_type
Sorun: Grant type desteklenmiyor
Çözüm: Sadece authorization_code ve refresh_token desteklenir
invalid_client
Sorun: Client authentication başarısız
Çözüm:
- client_id doğru mu?
- client_secret doğru mu? (confidential için)
- Basic Auth doğru encode edilmiş mi?
Standartlar ve RFC'ler
Atlantic ID aşağıdaki standartlara tam uyumludur:
- RFC 6749 - OAuth 2.0
- RFC 7636 - PKCE
- RFC 7519 - JWT
- RFC 7517 - JWK
- OpenID Connect Core 1.0
- OpenID Connect Discovery 1.0