OAuth 2.0 bir authorization framework''üdür — uygulamaların 3. parti kaynaklara (Google, GitHub) kullanıcı adına erişmesini sağlar. OpenID Connect (OIDC) bunun üzerine authentication katmanı ekler. Modern web auth''un standardı budur. Bu yazı kavramları netleştirir ve Authorization Code Flow''u adım adım anlatır.
Roller
İlgili rehberler: SSL sertifikası nasıl alınır · OWASP Top 10 2026 · JWT güvenlik · SQL injection önleme · Parola hash (BCrypt, Argon2)
- Resource Owner: Son kullanıcı
- Client: Uygulamanız — kullanıcı adına hareket eder
- Authorization Server: Kimlik sağlayıcı (Google, Auth0, Keycloak)
- Resource Server: API (GitHub API, Google Drive API)
Flow Türleri
- Authorization Code + PKCE: Modern web ve mobil için standart
- Client Credentials: Server-to-server (UI yok)
- Device Code: TV, CLI gibi browser''sız cihazlar
- Implicit: Deprecated, asla kullanmayın
- Password: Deprecated, asla kullanmayın
Authorization Code Flow (PKCE ile)
┌─────────┐ 1. Login butonuna tıkla
│ Client │ ────────────────────────────┐
│ (Web) │ ↓
└─────────┘ 2. Browser redirect →
↑ /authorize?client_id=X&redirect_uri=...
│ &code_challenge=HASH&state=RANDOM
│ │
│ ┌─────────────────────┴──┐
│ │ Authorization Server │
│ │ (kullanıcı login olur) │
│ └─────────────────────┬──┘
│ │
│ 3. Redirect back with code │
│ ←──────────────────────────────────┘
│ /callback?code=XXX&state=RANDOM
│
│ 4. Token exchange (server-side)
└──────→ POST /token
code=XXX&code_verifier=ORIGINAL
→ { access_token, refresh_token, id_token }
PKCE Neden Şart?
Public client (browser, mobile)''ın client_secret''ini güvenle saklayamazsınız. PKCE (Proof Key for Code Exchange): her login''de random bir code_verifier üret, onun SHA256 hash''ini code_challenge olarak /authorize''a gönder. Token exchange''te orijinal code_verifier''ı gösterince auth server doğrular.
// 1) PKCE challenge üret
import { randomBytes, createHash } from 'crypto';
const codeVerifier = randomBytes(32).toString('base64url');
const codeChallenge = createHash('sha256').update(codeVerifier).digest('base64url');
// Session'da sakla
session.codeVerifier = codeVerifier;
session.state = randomBytes(16).toString('hex');
// 2) Redirect URL oluştur
const params = new URLSearchParams({
response_type: 'code',
client_id: CLIENT_ID,
redirect_uri: REDIRECT_URI,
scope: 'openid profile email',
code_challenge: codeChallenge,
code_challenge_method: 'S256',
state: session.state
});
res.redirect(`https://auth.example.com/authorize?${params}`);
// 3) /callback endpoint
app.get('/callback', async (req, res) => {
const { code, state } = req.query;
if (state !== session.state) return res.status(400).send('Invalid state');
// Token exchange
const tokenRes = await fetch('https://auth.example.com/token', {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: new URLSearchParams({
grant_type: 'authorization_code',
code,
redirect_uri: REDIRECT_URI,
client_id: CLIENT_ID,
code_verifier: session.codeVerifier
})
});
const { access_token, id_token, refresh_token } = await tokenRes.json();
// id_token → OIDC user info
// access_token → API çağrıları
// refresh_token → access_token yenilemek için
});
OIDC: id_token
OAuth sadece yetki verir, kim olduğunu söylemez. OIDC id_token (JWT) ile kullanıcı kimliğini taşır. Içinde: sub (user id), email, name, iss (issuer), aud (audience), exp (expiry).
import { jwtVerify, createRemoteJWKSet } from 'jose';
const JWKS = createRemoteJWKSet(new URL('https://auth.example.com/.well-known/jwks.json'));
const { payload } = await jwtVerify(id_token, JWKS, {
issuer: 'https://auth.example.com',
audience: CLIENT_ID
});
// payload.sub, payload.email, payload.name
// Kendi DB'nize kullanıcıyı kaydet veya getir
let user = await db.users.findOne({ oauthSub: payload.sub });
if (!user) {
user = await db.users.create({
oauthSub: payload.sub,
email: payload.email,
name: payload.name
});
}
// Session veya JWT oluştur (kendi tokenın)
Scopes
Scope''lar access_token''ın hangi kaynaklara erişebileceğini belirler. Minimum gerekli scope''u iste — least privilege.
# OIDC temel
openid # zorunlu — id_token için
profile # name, picture
email # email, email_verified
# Provider-specific
read:user # GitHub
https://www.googleapis.com/auth/drive.readonly # Google Drive
Refresh Token
async function refreshAccessToken(refreshToken) {
const res = await fetch('https://auth.example.com/token', {
method: 'POST',
body: new URLSearchParams({
grant_type: 'refresh_token',
refresh_token: refreshToken,
client_id: CLIENT_ID
})
});
if (!res.ok) throw new Error('Refresh failed');
return await res.json(); // yeni { access_token, refresh_token (rotated) }
}
// Access token expire olunca otomatik yenile
if (tokenExpiresAt < Date.now()) {
const newTokens = await refreshAccessToken(session.refreshToken);
session.accessToken = newTokens.access_token;
session.refreshToken = newTokens.refresh_token; // rotated
session.tokenExpiresAt = Date.now() + newTokens.expires_in * 1000;
}
Güvenlik Kontrol Listesi
- state parametresi CSRF için zorunlu
- PKCE public client''ta zorunlu
- HTTPS tüm endpoint''lerde
- id_token signature ve iss/aud mutlaka doğrula
- Refresh token HttpOnly cookie''de veya secure backend''de
- Logout: front-channel veya back-channel — sessionId iptal
Sosyal Login Hızlı Kurulum
Tüm flow''u kendiniz yazmak yerine hazır library''ler: Passport.js (Node), NextAuth.js / Auth.js, Lucia Auth, Clerk, Supabase Auth. 10 satır config ile Google/GitHub/Apple login.
Web Güvenliği ve Uygulama Savunması
Modern web güvenliği katmanlı savunma (defense-in-depth) ile yapılır: TLS 1.3 ve HSTS ile şifreli iletişim, WAF (Web Application Firewall) ile OWASP Top 10 saldırılarına karşı koruma, BCrypt veya Argon2id ile parola hash'leme, JWT token'larında imza doğrulama (HMAC veya RSA), CSRF token + SameSite cookie ile cross-site istek koruması ve Content Security Policy ile XSS azaltma. SQL injection önleme için prepared statement, brute force için fail2ban veya rate limiting, DDoS koruması için Cloudflare/Anti-DDoS sağlayıcı zorunludur. Güvenlik açığı taraması (Burp Suite, OWASP ZAP) ve düzenli güvenlik denetimi; üretim ortamında veri sızıntısı ve hesap ele geçirme risklerini büyük ölçüde azaltır.
OAuth, SSO ve Keycloak gibi identity provider kurulumu için iletişime geçin