Kimlik Doğrulama
Starter kit, web kimlik doğrulama için Laravel Fortify'ı ve API kimlik doğrulama için Passport'u birlikte kullanır.
Web Kimlik Doğrulama
Hazır akışlar şunlardır:
- giriş
- kayıt
- şifremi unuttum
- şifre sıfırlama
- e-posta doğrulama
- şifre onayı
- iki faktör doğrulama ekranı
Bu ekranlar resources/js/pages/Auth/ altında yer alır.
Turnstile ayarlardan etkinleştirildiğinde login, register ve forgot-password formları ortak TurnstileWidget bileşenini render eder ve cf_turnstile_response sunucu tarafında doğrulanır.
Profil Güvenliği
Giriş yapmış kullanıcılar için ayrıca şu güvenlik araçları vardır:
- profil bilgisi güncelleme
- şifre güncelleme
- iki faktör ayarları
- recovery code görüntüleme ve yeniden üretme için şifre onayı
- tarayıcı oturum yönetimi
- avatar yükleme ve silme
Bu akışlar profil ekranı ve routes/web/profile-route.php içindeki ilişkili route'lar üzerinden çalışır.
Parola Politikası
Parola politikası, Ayarlar → Güvenlik → Parola Politikası yönetici sekmesi tarafından yönetilir. Kurallar auth.* ayar anahtarları olarak saklanır ve PasswordValidationRules tarafından runtime'da uygulanır.
| Ayar anahtarı | Uyguladığı kural |
|---|---|
auth.password_min_length |
Minimum karakter sayısı (varsayılan: 8) |
auth.password_require_mixed_case |
Büyük ve küçük harf zorunlu |
auth.password_require_numbers |
En az bir rakam zorunlu |
auth.password_require_symbols |
En az bir sembol zorunlu |
Her Fortify akışı aktif kuralları otomatik devralır — kayıt, şifre sıfırlama, şifre onayı ve profil şifre güncelleme. Yönetici kullanıcı oluşturma/güncelleme akışları da aynı kuralları uygular.
Politika değiştiğinde mevcut kullanıcıların parolaları geçersiz olmaz — yalnızca yeni gönderilen parolalar güncel kurala karşı ölçülür.
Parola geçerlilik süresi
auth.password_expiry_days değerini 0'dan büyük bir değere ayarlamak EnsurePasswordNotExpired middleware'ini etkinleştirir. password_changed_at zaman damgası yapılandırılan gün sayısından daha eski olan kimlik doğrulanmış kullanıcılar, parolalarını güncelleyene kadar adanmış, guest tarzı bir parola-süresi-doldu ekranına (password.expired rotası) yönlendirilir. 0 değeri (varsayılan) geçerlilik süresini tamamen devre dışı bırakır.
password_changed_at, her parola yazımında otomatik olarak güncellenir: kayıt, şifre sıfırlama, profil güncelleme ve yönetici kullanıcı oluşturma/güncelleme. Mevcut kullanıcılar, migration çalıştığında now() değeriyle geri doldurulduğundan, deploy tarihinden itibaren geçerlilik sürecini başlatırlar; anında süresi dolmuş duruma düşmezler.
Çalışma Zamanı Kuralları
- pasif kullanıcılar web oturumu başlatamaz; Fortify login pipeline'ı status değeri
activeolmayan hesapları engeller - login denemeleri IP ve email/IP kombinasyonlarına göre rate-limit edilir;
auth.login_throttle = '1'(varsayılan, sert limiter) olduğunda Fortify rate limiter aktiftir; Ayarlar → Güvenlik'ten'0'yapıldığında limiter tamamen kalkmaz, daha gevşek birlogin-relaxedtabanına geçilir — hiçbir admin ayarı web login'ini tamamen limitsiz bırakamaz. API auth route'ları bu ayardan bağımsız kendi sabitthrottle:5,1middleware'ini taşır. - iki faktör challenge akışının ayrı bir limiter'ı vardır
- iki faktör challenge'ı tek kullanımlık — yanlış kod, boş submit veya geçersiz recovery code challenge id'sini anında iptal eder; client yeni bir id almak için tekrar login olmak zorundadır
- forgot-password POST route'u, eşleşme anında dinamik olarak Turnstile middleware'i alır
- API'de self-delete blokelidir.
UserPolicy::deleteactor === target durumundafalsedönüyor, yaniDELETE /api/v1/users/{self}users.deleteizni taşıyan kullanıcılar için bile 403 dönüyor. Desteklenen tek self-removal akışı Profile UI'daki password-confirmed Fortify yolu.
Zaten açık olan bir oturumu kesmek
Yukarıdaki login anındaki kontrol, zaten açık bir oturuma ulaşamaz — aksi hâlde bir kullanıcıyı pasifleştiren yönetici, o kullanıcının çerezinin süresinin dolmasını beklemek zorunda kalırdı. Bu boşluğu iki parça kapatır.
EnsureUserIsActive middleware'i. StarterKitServiceProvider::boot() tarafından sk.active alias'ı olarak kaydedilir ve web ile api gruplarına eklenir; böylece mevcut bir kurulum bootstrap/app.php dosyasına dokunmadan composer update ile bunu alır. Her istekte kimliği doğrulanmış model üzerindeki status değerini okur ve değer operatörün deny-list'indeyse oturumu sonlandırır:
- API / JSON isteği → kitin dokümante edilmiş
ApiResponsezarfında403(zarf middleware içinde kurulur; bu yüzden biçimApiExceptionHandler'ın kayıtlı olmasına bağlı değildir). - Web isteği → stateful guard'dan çıkış yapılır, session invalidate edilir, CSRF token yeniden üretilir ve login anındaki engelin kullandığı aynı
sk-auth.inactivemetniyle isimliloginroute'una yönlendirilir. - Kimlik bilgisi kesilemeyen web isteği (
webgrubundan geçen bir token guard) veyaloginroute'u olmayan bir uygulama → düz403. Yönlendirme döngüye girerdi, çünkü sonraki istek aynı kimlik bilgisiyle gelir.
Bilinçli olarak fail-open'dır. users.status kolonunu kitin kontrol etmediği uygulamalara da gider ve toplu kilitlenme, bir saniye önce pasifleştirilmiş bir hesaba fazladan bir istek servis etmekten çok daha kötüdür. Şu durumlarda istek geçirilir: listelenen hiçbir guard'da kullanıcı yoksa; listelenen bir guard auth.guards altında tanımlı değilse ya da çözümlenirken hata fırlatıyorsa; modelde status attribute'u yoksa; status null, bool veya string'e normalize olmayan başka bir değerse; ya da normalize edilmiş değer deny-list'te değilse — bilinmeyen string'ler dahil. Middleware asla "active değil, o hâlde engelle" çıkarımı yapmaz; yalnızca açıkça listelenmiş bir status'ü engelleyebilir.
RevokeUserAccessAction. Middleware yalnızca web/api gruplarından geçen isteklere etki eder. Bir kullanıcının normalize edilmiş status değeri deny-list'teki bir değere geçtiğinde, bu action ek olarak Passport access ve refresh token'larını, kullanılmamış authorization/device code'ları (bunlar aksi hâlde hâlâ yeni bir access token'a çevrilebilir) ve kullanıcının veritabanı session satırlarını iptal eder. Yalnızca gerçek bir geçişte çalışır — bir yıldır pasif olan bir kullanıcının adını düzenlemek hiçbir şey iptal etmez — ve çağırana asla hata fırlatmaz, çünkü status yazımı zaten commit edilmiştir.
Yapılandırma — config/starter-kit.php, security bloğu:
| Anahtar | Varsayılan | Ne yapar |
|---|---|---|
security.enforce_active_status |
true |
Kill switch. false hem middleware'i hem de token iptalini devre dışı bırakır. |
security.active_status_denied |
['inactive', 'banned'] |
Oturumu sonlandıran tek status kümesi. Bilinçli olarak, gönderilen userStatus definition'ının ürettiği iki non-active değerle sınırlıdır. |
security.active_status_guards |
['web', 'api'] |
Her istekte incelenen guard'lar. |
security.csp_extra_origins |
[] |
Kitin Content-Security-Policy başlığına eklenen ek origin'ler. |
mergeConfigFromyalnızca üst seviye anahtarları birleştirir. Bu sürümden önce yayınlanmış birconfig/starter-kit.phphiçsecurityanahtarı taşımaz ve vendor bloğunu bütün olarak devralır; kısmi birsecuritydizisi taşıyan bir dosya ise yazmadığı her iç anahtar için vendor bloğunun yerine geçer. Bu yüzden middleware, gönderilen literal değerleri birebir tekrarlayan sınıf sabitlerine (EnsureUserIsActive::ENFORCE_DEFAULT/::DENIED_DEFAULT/::GUARDS_DEFAULT) düşer; her iki kitle de aynı değerleri çözer.
API Kimlik Doğrulama
API tarafında Passport kullanılır:
- personal access token desteği
POST /api/v1/auth/registervePOST /api/v1/auth/loginpublic'tir ve throttle uygulanırPOST /api/v1/auth/two-factor-challengepublic'tir ve throttle uygulanırPOST /api/v1/auth/logoutveGET /api/v1/auth/meiçinauth:apigerekir
API Auth Akışı
register, yalnızca email verification kapalıysa201ile{ user, token }döner- email verification açıkken
register, token vermeden201ile{ user, requires_verification: true }döner login,{ user, token },{ requires_verification: true }veya{ requires_two_factor: true, challenge }şekillerinden birini dönebilirtwo-factor-challenge, API 2FA akışınıcodeveyarecovery_codeile tamamlar ve başarı durumunda{ user, token }döner- istemciler, her başarılı auth yanıtında token beklemek yerine
requires_verificationverequires_two_factoralanlarına göre dallanmalıdır
Passport Yapılandırması
Token ömürleri ve scope kataloğu config/starter-kit.php dosyasında passport anahtarı altında tanımlanır ve boot sırasında StarterKitServiceProvider tarafından uygulanır (laravel/passport kurulu değilse no-op'tur).
Config anahtarı (passport.…) |
Env değişkeni | Varsayılan | Etkisi |
|---|---|---|---|
provider |
STARTER_KIT_PASSPORT_PROVIDER |
users |
Otomatik kaydedilen api guard'ının arkasındaki auth provider. Guard yalnızca uygulama zaten auth.guards.api tanımlamamışsa sentezlenir — kendi tanımladığınız bir custom guard asla ezilmez. |
access_token_minutes |
PASSPORT_TOKEN_MINUTES |
60 |
Access token TTL'i, Passport::tokensExpireIn() üzerinden uygulanır. |
refresh_token_days |
PASSPORT_REFRESH_TOKEN_DAYS |
14 |
Refresh token TTL'i, Passport::refreshTokensExpireIn() üzerinden uygulanır. |
personal_token_days |
PASSPORT_PERSONAL_TOKEN_DAYS |
30 |
Personal Access Token TTL'i, Passport::personalAccessTokensExpireIn() üzerinden uygulanır. |
scopes |
— | 5 örnek scope (users.read, users.write, files.read, files.write, admin) |
Passport::tokensCan() ile kaydedilen scope kataloğu. Aynı zamanda /admin/api-tokens üzerinden bir PAT oluşturulurken StoreApiTokenRequest'in doğruladığı allow-list'tir — bu katalog dışında bir scope istemek, Passport'a hiç ulaşmadan validation hatasıyla reddedilir. Katalogda bulunsa bile literal * allow-list'ten çıkarılır, yani UI üzerinden wildcard scope'lu bir PAT asla oluşturulamaz. |
default_scopes |
— | [] (boş) |
Passport::setDefaultScope() ile uygulanan scope(lar). Yalnızca scopes doluyken etkilidir. |
Set edildiğinde (null olmayan, boş olmayan bir string) hâlâ öncelikli olan iki legacy env değişkeni vardır:
PASSPORT_TOKEN_DAYS(gün) —access_token_minutes'ı ezer; değer dakikaya çevrilmek için24 * 60ile çarpılır.PASSPORT_PERSONAL_TOKEN_MONTHS(ay) —personal_token_days'i ezer; değer güne çevrilmek için30ile çarpılır.
İkisi de sırasıyla passport.access_token_days / passport.personal_token_months config anahtarlarına eşlenir; bu anahtarların varsayılanı null'dur — set edilmedikleri sürece yukarıdaki dakika/gün anahtarları geçerli olur.
Scope enforcement opt-in'dir. passport.scopes'u doldurmak tek başına hiçbir şeyi kısıtlamaz — yalnızca katalog ve (isteğe bağlı) default'u kaydeder. Bir route'u gerçekten kısıtlamak için Passport'un kendi scope/scopes middleware'ini route'a eklemeniz gerekir (örn. ->middleware('scope:users.read')). scopes'u boş bırakmak Passport'un implicit * scope'unu korur, böylece mevcut istemciler ve token'lar değişmeden çalışmaya devam eder. /admin/api-clients üzerinden oluşturulan OAuth2 istemcilerinin hiç scope taşımadığını unutmayın (kaldırıldı — bkz. API İstemcileri ve Token'lar); yukarıdaki scope kataloğu yalnızca Personal Access Token'lar için geçerlidir.
API İstemcileri ve Token'lar
Admin paneli, Passport OAuth2 istemcilerini ve Personal Access Token'ları (PAT) yönetmek için bir arayüz sunar:
/admin/api-clients— OAuth2 istemcilerini listele, oluştur, güncelle ve sil/admin/api-tokens— Personal Access Token'ları yönet
İstemci secret'ları ve PAT değerleri yalnızca oluşturma anında dismiss edilemeyen bir modal içinde bir kez gösterilir; plaintext olarak hiçbir zaman saklanmaz. Ayrıntılı belge için bkz. API İstemcileri ve Token'lar.
Notlar
- tarayıcı tarafındaki auth deneyimi için Fortify kullanın
- harici veya token tabanlı API tüketicileri için Passport kullanın
- aynı user model kullanılsa bile web ve API auth sorumluluklarını ayrı düşünün