RbnAuth — Kimlik doğrulama, oturum, rol ve parola kurtarma
Doğrulanan kod tabanı:
d49b4413(dalfeat/fw-license-master) · Tarih: 2026-10-05 · Yayın: 0.9.7 = bu commit + sonrası; belge yalnız doğrulama anındaki kodu anlatır
Kaynak klasör:Bundles/RbnSuite/RbnAuth/— 15*.php
(Controllers 3 · Handlers 5 · Services 2 · Models 3 · Middleware 1 · Support 1)
Envanter: 15 php dosyasının 15'i aşağıdaki tabloda anlatıldı.
Bu paket 20 eşiğinin altında olduğu için tek belge yeterlidir (alt dal belge
üretilmedi — kaynak ağacı hâlâ tamamen kapsanmıştır).
1. Ne işe yarar, kimler kullanır
RbnAuth, framework'ün giriş kapısıdır: kimlik doğrulama, oturum yaşam döngüsü,
rol tabanlı yetkilendirme (ACL), "beni hatırla", parola sıfırlama, e-posta
doğrulama ve tüm bunların denetim izi (audit).
RbnAdmin ve RbnStudio bu pakete bağımlıdır: ikisi de admin middleware grubu
altında çalışır (Core/Routes/Mappings/core.php:75) ve o grubun middleware'i
AuthMiddleware'dir. RbnAdminService::saveColors() yetkisini
handler('access')->can('admin') ile buradan sorar (RbnAdminService.php:28).
Rotaları kendi yazmaz. RbnAuth'in tek registerRoutes() metodu yoktur;
rotaları framework'ün kendi haritasında tanımlıdır:
Core/Routes/Mappings/auth.php:10. Bu, RbnAdmin/RbnStudio'dan farklıdır
(ikisi ModuleData::registerRoutes() kullanır).
Görünümleri de yoktur. Giriş/kayıt ekranları
Resources/Views/RbnAuth/ altındadır (3 dosya: auth.rbn.php,
Layouts/auth_header.rbn.php, Layouts/auth_footer.rbn.php) ve
AuthViewController bunları render('auth', 'login') iki argümanlı (eski)
imzayla basar (Controllers/AuthViewController.php:47).
2. Dosya envanteri (15 dosya)
2.1 Controllers/ — 3
| Dosya | Görev | Önemli public yöntemler (imza) |
|---|---|---|
AuthController.php |
Giriş/çıkış uçları. #[Module(name:'rbnauth', context:'auth', data: ModuleData::class)] (:19) |
authenticate(), loginSubmit(), logoutSubmit(), logout() |
AuthActionController.php |
AuthController'dan türer (:23); kayıt + kurtarma işlemleri |
verifyEmail(), registerSubmit(), forgotPasswordSubmit(), resetPasswordSubmit(), korumalı confirmPasswordMatches(array $data): bool (:199) |
AuthViewController.php |
Giriş/kayıt/kilit/şifre ekranları — #[Module] özniteliği yok, düz BaseController (:17) |
showLogin(), showRegister(), showLockscreen(), showForgotPassword(), showVerifyCode(), showResetPassword(), showUserDashboard(?string $path=null), korumalı getDashboardUrl(string $role): string |
2.2 Handlers/ — 5
| Dosya | Görev | Önemli public yöntemler |
|---|---|---|
AccessHandler.php |
Giriş doğrulaması + rol denetimi + çıkış | authenticate(string $identity, string $password): array (:40), can(string|array $requiredRole): bool (:188), terminate(): bool (:227); korumalı: equalizeVerifyTiming(string), observeMasterIpBan(string): mixed, satirDegeri($satir, string $alan), upgradePasswordHash(int,string,string), forgetCookie(string) |
SessionHandler.php |
Oturum açma, kilitleme, remember-me | start($user, bool $isMaster=false, bool $remember=false): void (:22), lock(): void (:154), korumalı createRememberMe(int $userId, bool $isMaster=false) (:175), regenerateSessionId(): bool (:91), destroySessionFallback(): void (:117) |
LifecycleHandler.php |
Kayıt / doğrulama / parola sıfırlama yazıcıları | createIdentity(array $data): array (:69), confirmIdentity(int $userId): bool (:158), completeReset(int $userId, string $newPassword): bool (:203); statik deriveNameAndUsername(array $data): array (:44); sabitler NAME_MAX_LENGTH=200, USERNAME_MAX_LENGTH=100 (:23,26) |
CredentialHandler.php |
E-posta/parola politikası + token kasası | validateEmail(string): array\|true (:23), validatePassword(string): array\|true (:60), calculateScore(string): int (:146), issueVaultToken(int $userId, string $type, int $hours=2): string (:188); korumalı containsSequentialRun(string): bool (:108) |
AuditHandler.php |
Çok kanallı denetim günlüğü | logSuccess(int $userId, string $identity, string $accountType='user') (:83), logFailure(string $identity, string $reason, string $accountType='user') (:172), logSecurityBlock(string $ip, string $reason) (:191), clearLoginFailureCounters(string $ip): bool (:136); statik maskIdentity(string): string (:34), sanitizeText(string, int $maxLength=200) (:70) |
2.3 Services/ — 2
| Dosya | Görev | Önemli public yöntemler |
|---|---|---|
AuthService.php |
Giriş/çıkış orkestrasyonu + oturumdaki kimlik kaynağı | check(): bool (:26), login(string $identity, string $password, bool $remember=false): array (:35), user(): ?array (:151), logout(): bool (:173) |
RecoveryService.php |
Kayıt + kurtarma akışının orkestratörü | register(array $data): array (:42), initiateRecovery(string $email): array (:92), reset(string $rawToken, string $newPassword): array (:139), verify(string $rawToken, int $expectedUserId=0): array (:192), canShowResetForm(string $rawToken): bool (:230); korumalı: resetFlow, verifyFlow, claimToken(string,string): array, tokenErrorMessage(string): string, deliverLink(string,$subject,$view,$name,$token,int): bool |
2.4 Models/ — 3
| Dosya | Görev | Önemli üyeler |
|---|---|---|
AuthRole.php |
Rol tablosu (TEK kaynak) | ROLES (7 rol, level 5–100), ADMIN_ROLES (5 rol), BYPASS_ROLES (3 rol) |
AuthIdentity.php |
Paket kimliği + SEO + görünüm metinleri | THEME_COLOR, FAVICON, AUTH_IDENTITY, DEFAULT_INFO (6 ekran), VIEW_MAP |
ModuleData.php |
Kayıt merkezi | CONFIG (:26), registerMap(): array (:53) |
2.5 Middleware/ — 1
| Dosya | Görev | Önemli public yöntemler |
|---|---|---|
AuthMiddleware.php |
Tüm rota güvenlik adımlarının tek orkestrasyonu | handle(?string $requiredRole=null): void (:28); statik lockedPostAllowed(string $path): bool (:188); korumalı: ensureSessionPersistence(), clearRememberCookie(), verifyFingerprint(mixed), enforceLockscreen() |
2.6 Support/ — 1
| Dosya | Görev | Önemli üyeler |
|---|---|---|
RememberTokenService.php |
"Beni hatırla" token'inin süreli ve imzalı biçimi (saf statik sınıf) | VERSION='v2', MAX_AGE_DAYS=30, MAX_AGE_SECONDS=2592000, LEGACY_ACCEPT_UNTIL=1793566800; issue(?int $now=null): array, isSigned(string): bool, isAcceptable(string, ?int $now=null): bool, expiresAt(string): ?int; korumalı isLegacyAcceptable, signature |
2.7 Kayıt haritası (ModuleData::registerMap(), :53-72)
services : auth → AuthService, recovery → RecoveryService
handlers : access → AccessHandler, session → SessionHandler,
lifecycle → LifecycleHandler, credential → CredentialHandler,
audit → AuditHandler
constants : role → AuthRole, auth → AuthIdentity
Kayıt defteri boş dönmüyor: framework bu haritayı paket adı altında birleştirir
(SystemRegistry.php:45). AuthMiddleware ve RememberTokenService bu haritada
yoktur — middleware RouteBlueprint::MIDDLEWARE['aliases']['auth'|'guard']
üzerinden (Core/Support/Definitions/Route/RouteBlueprint.php:42), destek sınıfı
doğrudan use edilerek bağlanır.
3. Akışlar
3.1 Giriş (POST /auth/login)
POST /auth/login → Core/Routes/Mappings/auth.php:21
→ AuthController::loginSubmit() AuthController.php:33
→ request->form(['email'=>'required|email','password'=>'required'],
['rateLimitEnabled'=>true,'action'=>'login']) :36-42
→ AuthService::login($email,$password,$remember) AuthService.php:35
├─ ADIM 1: repository('project.user')->findMasterDeveloper($identity) :40
│ ├─ varsa parola doğrular → SessionHandler::start($master,true,$remember) :48
│ │ → admin_panel_disabled ise rolü 'user' yapıp '/user' döner :54-63
│ │ → değilse Route->url('',[], 'admin') döner :65-69
│ └─ AuditHandler::logSuccess(..., 'master') :49
└─ ADIM 2 (master değilse): AccessHandler::authenticate() Handlers/AccessHandler.php:40
├─ Adım 1 : repository('project.userSecurity')->isIpBlocked($ip) :45
├─ Adım 1b: master ban LİSTESİ **gözlenir**, engellemez :76-83
├─ Adım 2 : findByIdentity() → yoksa DUMMY_HASH ile eşit maliyet :88-95
├─ Adım 3 : isActive() → pasifsa aynı eşit maliyet :99-106
├─ Adım 4 : crypto->verify() → hatalıysa service('ipGuard')->recordHit($ip,'login') :109-119
│ başarılıysa upgradePasswordHash() :122
└─ Adım 5 : AuditHandler::logSuccess() :125
├─ ADIM 3: SessionHandler::start($user,false,$remember) Handlers/SessionHandler.php:22
│ → EN ÖNDE regenerateSessionId() (session fixation) :44
│ → parola özeti eskiyse sessiz yenilenir :44 (AccessHandler:122)
├─ ADIM 4: required_login_role kontrolü → yetersizse logout() + hata :98-111
└─ ADIM 5: admin_panel_disabled / rol yönlendirmesi :113-145
→ Route->handleResult($result, …) :49-53
Hata sızıntısı kapatması: loginSubmit()'ın catch bloğu istisna mesajını
kullanıcıya göstermez, yalnız error_log()'a yazar ve sabit mesaj döner
(AuthController.php:54). Gerekçe yorumda açık: canlıda kullanıcıya
SQLSTATE[42S22]: Unknown column 'type' in 'where clause' sızmıştı.
3.2 Çıkış — iki yol, kasıtlı
| Yol | CSRF | Davranış |
|---|---|---|
POST /auth/logout → logoutSubmit() (:89-100) |
zorunlu (rawAll(['csrf'=>true,'logOnlySayac'=>false])) |
Çıkış yapılır |
GET /logout, GET /cikis → logout() (:120) |
yok | LOG-ONLY logout_get_deprecated sayacı; çapraz-site istekte 403 + çıkış yapılmaz |
Çapraz-site tespiti iki kaynaktan olur: Sec-Fetch-Site: cross-site başlığı
(:134-135) ve Referer ana makinesinin HTTP_HOST ile karşılaştırılması
(:138-151). Başlıkların ikisi de yoksa (curl, PowerShell) çıkış yapılır —
aksi hâlde meşru bağlantılar kırılırdı (:112-116).
Kimlik eşleşmesi (A-14): çıkış yalnız oturumdaki kimliğe ait token'ı düşürür.
Master tokenı koşulsuz temizlenmez; yalnız oturumun kendisi master
geliştirici kimliğiyle açıldıysa (AuthController.php:184).
3.3 Middleware zinciri (her korumalı istekte)
AuthMiddleware::handle(?string $requiredRole) AuthMiddleware.php:28
├─ 1 ensureSessionPersistence() → 'rbn_remember' çerezinden oturum kurma :33,59-105
│ └─ önce RememberTokenService::isAcceptable($token) (süre + imza) :76
├─ 2 check() → değilse response()->redirect('/') + exit :36-39
├─ 3 verifyFingerprint() → IP+UA sha256 değiştiyse logout + çıkış :42,132-145
├─ 4 enforceLockscreen() → kilitliyken yalnız izinli POST'lar :45,150-181
│ └─ lockedPostAllowed(): TAM eşleşme '/auth/login', '/auth/authenticate' :188-206
└─ 5 can($requiredRole) → değilse shield()->forbidden(...) :48-53
Middleware alias'ları: auth, guard → AuthMiddleware; gruplar: user,
admin, superadmin, developer → ['auth', 'role:<x>']
(Core/Support/Definitions/Route/RouteBlueprint.php:40). /user paneli
Route::role('user')->prefix('user') grubunda tanımlıdır
(Core/Routes/Mappings/auth.php:51).
3.4 Parola sıfırlama (token zorunlu)
GET /reset-password?token=T → AuthViewController::showResetPassword() :150
└─ RecoveryService::canShowResetForm(T) → repository->peek() (tüketmez) :230-243
POST /auth/forgot-password → forgotPasswordSubmit() :112
→ RecoveryService::initiateRecovery($email) RecoveryService.php:92
├─ hesap yoksa: sabit maliyetli password_verify() + AYNI nötr mesaj :104-109
└─ hesap varsa: issueVaultToken(…, 'password_recovery', 1 saat) + e-posta
POST /auth/reset-password → resetPasswordSubmit() :143
├─ form: token(required|string), password(required|min:N),
│ confirm_password(required|string), csrf + rateLimit('password_reset') :145-162
├─ confirmPasswordMatches() → hash_equals() :168,199-209
└─ RecoveryService::reset($token,$password) → claimToken() (TEK KULLANIMLIK)
→ LifecycleHandler::completeReset() → z_users_security.password_hash
+ remember_token = NULL
+ revokePending(...) LifecycleHandler.php:203
E-posta doğrulama da aynı kalıpta: verifyEmail() (:38) uid + token ister,
RecoveryService::verify() token'ı tüketir, uid ile token sahibi örtüşmezse
aktivasyon olmaz (RecoveryService.php:213).
4. Yapılandırma / ayar anahtarları ve varsayılanlar
| Değer | Kaynak satırı | Varsayılan / etki |
|---|---|---|
RouteBlueprint::LOGIN_PATH |
Core/Support/Definitions/Route/RouteBlueprint.php:75 |
'rbn-admin' — gizli giriş yolu; robots.txt'te ilan edilmez (AuthViewController.php:44) |
dashboard_prefix |
AuthViewController.php:36 |
Boşsa LOGIN_PATH kullanılır (:38); 'user' dışında herhangi bir değer admin girişi sayılır (:41) |
remember_me_duration |
SessionHandler.php:214 |
ARTARAK KULLANILMAZ; tek kaynak RememberTokenService::MAX_AGE_SECONDS (30 gün) |
| Token ömrü — e-posta doğrulama | RecoveryService.php:28 |
EMAIL_VERIFICATION_HOURS = 24 |
| Token ömrü — parola kurtarma | RecoveryService.php:31 |
PASSWORD_RECOVERY_HOURS = 1 (60 dk) |
| Token TTL kırpma | CredentialHandler.php:197 |
max(1, min($hours, 24)) saat |
| Parola en kısa uzunluk | PasswordValidations::MIN_PASSWORD_LENGTH |
CredentialHandler.php:68,71 · AuthActionController.php:71,148 |
required_login_role |
AuthService.php:90 |
Boşsa kapı yok; doluysa rol seviyesi karşılaştırılır (:98-111) |
admin_panel_disabled |
AuthService.php:52,113 |
Rol user'a zorlanır, yönlendirme /user olur |
user_dash_controller |
AuthViewController.php:174 |
Yoksa ortak RbnCommon/userdash şablonu basılır (:231) |
| Hız sınırı eylem adları | AuthActionController.php:41,81,119,161 |
login, register, password_reset; kanonik ad RateLimitValidations::canon() ile (AuditHandler.php:145) |
z_users.is_active |
LifecycleHandler.php:117,170 |
2 = e-posta bekliyor, 1 = doğrulandı |
LEGACY_ACCEPT_UNTIL |
RememberTokenService.php:60 |
1793566800 = 2026-11-01 21:00:00 UTC (2026-11-02 00:00 Europe/Istanbul) — ölçüldü |
5. Tuzaklar ve kurallar (kodda ölçülmüş)
-
Çıkış sırası bir daha bozulmamalı.
SessionHandler::start()en başında
regenerateSessionId()çağırır (SessionHandler.php:44), çünkü
session_regenerate_id(true)eski oturum dosyasını siler.createRememberMe()
bundan sonra çağrılır (:75-77) — sıra tersine çevrilirse remember-me çerezi
ölü oturuma bağlanır ve "1 giriş sonra hatırlanmıyorum" hatası doğar
(:161-167). -
Master (global) IP ban listesi girişi engellemez.
AccessHandler
rbn_master.ip_blocks'ı yalnız gözlemler (observeMasterIpBan(),:147-163)
ve audit'a "would-block" yazar (:76-83). Ölçülen gerekçe yorumda: bu kayıtlar
tamamen 127.0.0.1'e ait ve global; bağlansaydı tüm yerel girişler kapanırdı.
observeMasterIpBan()bilinçli olarak fail-open'dır (:140-145) — engelleme
kararıshield_ip_guard_modeanahtarına aittir. -
DUMMY_HASHgerçek bir hesaba ait değildir.AccessHandler.php:24—
rastgele bir bcrypt özeti;equalizeVerifyTiming()(:30-33) bununla
crypto->verify()çağırıp kullanıcı yokken de aynı maliyeti üretir (zamanlama
sızıntısı kapatması).RecoveryService::initiateRecovery()aynı amaç için
ayrı bir sahte hash kullanır (:106) — iki yer, iki sabit. -
AccessHandler::can()seviye karşılaştırması yapar, isim karşılaştırması
değil. Dizi hâlinde roller verildiğinde önce ad eşitliği, sonra
seviye karşılaştırılır (:206-217); tekil rolde yalnız seviye
(:220-221). Bu yüzden'moderator'(60) istiyorsaeditor(40) geçmez —
doğru; amaAuthRole::ADMIN_ROLESüyeliği (5 rol) ile
can('admin')(seviye 80 → 5 rolün 4'ü geçer,moderator60 geçmez)
aynı şey değildir. -
AuthController#[Module]taşır,AuthViewControllertaşımaz.
AuthViewController(AuthViewController.php:17) düzBaseController'dır;
#[Module]yalnız sınıfın kendisine değil, sınıf hiyerarşisine bakan
IdentityExtractorTrait'e yansır (ComponentHydratorTrait.php:35) ve
hiyerarşi taramasıparent::classyönünde yukarı gider — yani alt sınıf
üst sınıfın özniteliğini görmez.AuthActionController extends AuthController(AuthActionController.php:23) bu yüzden#[Module]'ı
miraslar;AuthViewControllerhiçbir modül kimliğine sahip değildir ve
contextdeğeriAuthViewController::showUserDashboard()içinde elle
atanır (:230). -
AuthRole::BYPASS_ROLESburadan okunmaz, başka yerden.FormGuardHandler
hız sınırı/honeypot muafiyeti için bu listeyi kullanır
(Core/Http/Security/Handlers/FormGuardHandler.php:162); RbnAuth içinde
referansı yoktur. Yanideveloper/superadmin/adminform korumalarından
muaftır —moderatorveeditordeğildir (AuthRole.php:99). -
AuditHandler::logFailure()dosyaya maskeli, DB'ye düz yazar.
Dosya logumaskIdentity()kullanır (AuditHandler.php:179), DB kaydı
logFailedActivity()çağrısında ham$identity'yi gönderir (:185) —
kasıtlı: paneldeki "başarısız giriş denemeleri" listesi bu kayda dayanıyor,
maskelenirse savunma yeteneği kaybolurdu (:168-170). -
clearLoginFailureCounters()yalnız giriş sayacını siler. Önceki sürümde
unblockIp()tüm nedenli ban kayıtlarını siliyordu; ölçülen sonuç: meşru
kullanıcının girişi, aynı NAT/CGNAT IP'sindeki saldırganın yasağını da
düşürüyordu. Artık yalnız kanonikloginaksiyonunun sayacı silinir
(:136-158). Ban kayıtlarına dokunulmaz. -
VIEW_MAPveDEFAULT_INFOiki farklı yoldan okunur — yedekli bir
yapı.ModuleData::CONFIG['configs']ikisinin bir kopyasını taşır
(Models/ModuleData.php:42), amaAuthHandlerdoğrudan sabitlerden
okur:$configs = AuthIdentity::VIEW_MAP(Core/Render/Handlers/UI/AuthHandler.php:30),
$defaults = AuthIdentity::DEFAULT_INFO(:31), vemoduleDatavarsa
configs.default_infokopyasını tercih eder (:39) — yani veri tek
kaynaktan gelir, kopya yalnız yedek.VIEW_MAPgörünüm adını
DEFAULT_INFOanahtarına çevirir (:38:'forgot-password' → 'forgot').
Konvansiyon notu:VIEW_MAPbir görünüm → bilgi anahtarı eşlemesidir,
modül eşlemesi değil. RbnAdmin'dePanelIdentity::VIEW_MAPgerçekten ölüdür
(panel görünümleri metinlerini kendi dosyalarında yazar ve hiçbirAuthHandler
benzeri tüketici yoktur). -
AuthIdentity::DEFAULT_INFO['forgot']ve['verify']bayat metin.
forgot.featuresiçinde "Geçici Erişim Kodu Desteği" veverifybaşlığında
"Kodu Doğrula" / "15 Dakika Boyunca Geçerli Kod" yazıyor
(AuthIdentity.php:70), ama 6 haneli kod akışı kaldırıldı
(AuthViewController::showVerifyCode(),:132-139, artık
/forgot-password'a yönlendiriyor) ve parola sıfırlama 60 dakika.
Bu metinler ekranda görünüyorsa yanlış bilgilendirmedir. -
showVerifyCode()kasıtlı olarak ölü bir uçtur. Rota da kaldırılmıştır
(Core/Routes/Mappings/auth.php:37: "hedef metot hiç yoktu"); metot
geride kalmıştır ve kullanıcıyı bilgilendirerek/forgot-password'a
gönderir (AuthViewController.php:134). -
CredentialHandler::validatePassword()giriş yolunda çalışmaz.
Kapsam dışı olduğu açıkça yazılıdır (CredentialHandler.php:55): mevcut
kısa parolalı kullanıcılar bozulmasın diye yalnız yeni parola belirleyen
akışlarda (kayıt, sıfırlama) çağrılır. -
validatePassword()girişte kısa parola denetlemez, ama
AccessHandler::authenticate()uzunluk denetlemez — yani 3 karakterli
bir parola ile giriş mümkündür. Bu bilinçli bir geriye uyum kararıdır. -
AuthViewController::showLogin()yalnız admin yolunu basar. Son kullanıcı
portalı için/loginisteğiresponse()->redirect('/')ile ana sayfaya
döner (:51-52) — yani kullanıcı giriş ekranı framework'ün kendi
authgörünümü dışında bir yerden gelmelidir. -
SessionHandler::createRememberMe()yalnız normal kullanıcı kovasında
satır yoksacreate()yapar (:198-209) — iki yazma yolu (update/create)
elle ayrılmıştır. -
upgradePasswordHash()sessizce yutuyor.A-17gereği başarısızlık
girişi bozmaz (AccessHandler.php:291), amasaveSecurityData()tamamen
başarısız olursa parola özeti eski kalır ve hiçbir log yazılmaz. -
LifecycleHandler::createIdentity()z_users'apassword_hashYAZMAZ.
Yorumda ölçülmüş şema kanıtı var (LifecycleHandler.php:100): bu kolon
z_users'ta yok; kasaz_users_security.password_hash'tir. Aynı gerekçe
completeReset()içinde tekrarlanır (:193-196). -
AuthService::login()master geliştirici parolasınıcrypto->verify()
ile doğrular amaz_usersşemasını kullanmaz — master tablosundaki
passwordkolonundan okur (AuthService.php:44). -
request->form()ilerawAll()ayrımı güvenlik kontrolüne bağlı.
Parola tekrarırawAll()'a taşınmaz çünkü ham yol güvenlik kontrolünü
baypas ederdi (AuthActionController.php:149); buna karşılık çıkış
rawAll(['csrf'=>true])kullanır, çünkü amacı yalnız kalkan zinciri
(AuthController.php:91).
6. Örnek (gerçek koddan)
Statik, saf yardımcı — birim testlenebilir örnek (kırpma kuralı):
// Bundles/RbnSuite/RbnAuth/Handlers/LifecycleHandler.php:60-63
return [
'name' => mb_substr($name, 0, self::NAME_MAX_LENGTH), // 200
'username' => mb_substr($finalUsername, 0, self::USERNAME_MAX_LENGTH), // 100
];
Token biçimi (üç nokta ile ayrılmış, imzalı):
// Bundles/RbnSuite/RbnAuth/Support/RememberTokenService.php:75
'token' => $expiresAt . '.' . $nonce . '.' . self::signature($expiresAt, $nonce),
// imza: HMAC-SHA256(uygulama anahtarı, "rbn_remember:v2:<expires>:<nonce>")
7. İlgili belgeler
- RbnAdmin — panelin bu pakete bağımlı rotaları
- RbnStudio
- kavramlar/01-mimari-harita — açılış, oturum, render
- kavramlar/03-veritabani-ve-kiracilik —
z_users,z_users_security, kapsam - Core/Http —
form(),rawAll(),Validator,FormGuardHandler - Core/Routes —
RouteBlueprint::MIDDLEWARE, rota grupları - Core/Base/Services —
BaseService,BaseProvider,BaseChannel - acik-sorular