04.4 — Mobil Uygulamalar (iOS & Android)
Kimin için: React Native, Flutter, Swift (iOS) veya Kotlin (Android) mobil geliştiricileri.
Ön koşul: RFC 8252 OAuth 2.0 for Native Apps prensipleri.
Tahmini süre: 20 dakika.
Ne Öğreneceksiniz
- iOS (
ASWebAuthenticationSession) ve Android (Custom Tabs) ile güvenli tarayıcı oturumunu, - Özel URI şemaları (Custom Scheme) veya Universal/App Links ile geri dönüş yakalamayı,
- Mobil cihazda tokenları şifreli kasada (Keychain / Keystore) saklamayı.
Mobil Giriş Akış Mimarisi
Mobil uygulamalarda WebKit/WebView içinde şifre girişi yapılması güvenlik açığıdır. İşletim sisteminin sunduğu güvenli tarayıcı oturumları kullanılmalıdır:
- iOS:
AuthenticationServices.ASWebAuthenticationSession— Safari çerezlerini paylaşır, otomatik doldurma ve FaceID/TouchID passkeyleri destekler. - Android:
androidx.browser.customtabs.CustomTabsIntent— Chrome/varsayılan tarayıcı altyapısını güvenle uygulama içinde sekmeli olarak açar.
text
[Mobil Uygulama] ---> ASWebAuthenticationSession / Custom Tabs ---> [TALOST ID Giriş Ekranı]
|
[Mobil Uygulama] <--- Custom Scheme (myapp://oauth/callback?code=...) <----+
Yapılandırma ve Redirect URI
- Geliştirici Portalından uygulamanız için bir Public Client açın.
- Yönlendirme adresi olarak uygulamanızın özel şemasını tanımlayın:
talostdemo://oauth/callback - İşletim sistemi yapılandırmanızı tamamlayın:
- Android:
AndroidManifest.xmliçindeintent-filtertanımlayın. - iOS:
Info.plistiçindeCFBundleURLTypestanımlayın.
- Android:
Kod Örnekleri
1. iOS (Swift + AuthenticationServices)
swift
import Foundation
import AuthenticationServices
import CryptoKit
class AuthManager: NSObject, ASWebAuthenticationPresentationContextProviding {
var webAuthSession: ASWebAuthenticationSession?
func startLogin() {
// 1. PKCE üretimi
let verifier = generateRandomBase64Url(length: 32)
let challenge = computeSha256Base64Url(input: verifier)
let state = UUID().uuidString
let issuer = "https://id.talost.com"
let clientId = "cli_dev_xxxxxxxxxxxx"
let redirectUri = "talostdemo://oauth/callback"
guard let authUrl = URL(string: "\(issuer)/oauth/authorize?response_type=code&client_id=\(clientId)&redirect_uri=\(redirectUri)&scope=openid%20profile%20email&state=\(state)&code_challenge=\(challenge)&code_challenge_method=S256") else { return }
// 2. ASWebAuthenticationSession Başlat
webAuthSession = ASWebAuthenticationSession(url: authUrl, callbackURLScheme: "talostdemo") { callbackURL, error in
guard error == nil, let callbackURL = callbackURL else {
print("Giriş iptal edildi veya hata: \(String(describing: error))")
return
}
// 3. Callback parametrelerini ayıkla
if let components = URLComponents(url: callbackURL, resolvingAgainstBaseURL: false),
let code = components.queryItems?.first(where: { $0.name == "code" })?.value {
self.exchangeCodeForTokens(code: code, verifier: verifier, redirectUri: redirectUri)
}
}
webAuthSession?.presentationContextProvider = self
webAuthSession?.prefersEphemeralWebBrowserSession = false
webAuthSession?.start()
}
func presentationAnchor(for session: ASWebAuthenticationSession) -> ASPresentationAnchor {
return UIApplication.shared.windows.first { $0.isKeyWindow } ?? ASPresentationAnchor()
}
private func exchangeCodeForTokens(code: string, verifier: string, redirectUri: string) {
// POST /oauth/token isteği atıp token'ları Keychain'e yazın
}
}
Güvenlik Notları
- Mobil uygulamaya gömülen ikili dosyalar kaynak koda dönüştürülebilir (reverse-engineering). Bu nedenle
client_secretkesinlikle mobil kod içerisine konulmamalıdır. - Alınan
refresh_tokenveaccess_tokendeğerleri:- iOS tarafında Keychain Services,
- Android tarafında EncryptedSharedPreferences ile AES-256 şifreli olarak saklanmalıdır.
İlgili Sayfalar
Son doğrulama: 2026-10-04 · Kaynak: _envanter.md, src/lib/apps/redirect-uri.ts
Son doğrulama: 2026-10-04 · Kaynak: `_envanter.md`, `src/lib/apps/redirect-uri.ts`