Update SimpleIdentity přihlášeného uživatele bez reinit session
- fulda
- Člen | 3
Zdravím,
řeším pro zkušené možná triviální problém, ale nevím jak z něj.
Mám presenter pro změnu osobních údajů (jméno, atp.). Změny prováním
pomocí ajax+snippetů. Co položka to snippet a vlastní formulářík na
stránce na změnu hodnoty. Problém je, že některé položky např. jméno
bych potřeboval po změně a uložení do DB logicky updatovat i v aktuální
identitě.
Šel jsem na to naivně a po změně při zpracování formu jsem vytvořil
novou SimpleIdentity a zavolal $user->login() s novou identitou. To sice
aktualizuje identitu, ale přestanou pak fungovat snippety. Metodou pokus omyl
jsem došel k závěru, že login nastaví novou session a tím to celé asi
odejde, protože snippety přijímají jiná resp. žádná data
v payload…
Lze nějak updatovat identitu se zachováním session resp. v kombinaci se snippety? Jak se toto řeší? Nechat uživatele odhlásit/přihlásit pro aplikaci změn mi nepřijde úplně dobré řešení.
Ještě mě napadlo mít v identitě jen ID uživatele a pak všechno ostatní okolo uživatele vždy vytahat z DB v případě potřeby. To ale to taky není úplně optimální, že – když se data identity téměř nikdy po přihlášení nemění.
Btw. Jak v knihovně naja (event ‚complete‘) zjistím, který snippet byl aktualizován?
- Kamil Valenta
- Člen | 833
Sessid se mění, login() nejprve zavolá logout(true).
Nestačilo by si jen přepsat wakeupIdentity()?
Editoval Kamil Valenta (4. 3. 15:31)
- fulda
- Člen | 3
wakeupIdentity() jsem prozkoumal i vyzkoušel, ale není to úplně ono. Jednak asi nechci, aby to neustále při každém requestu updatovalo identitu z DB (proč, když toto je řešení velmi okrajové situace a aplikuje se pouze v momentě, kdy si uživatel bude měnit osobní údaje). A pak to samozřejmě nefunguje pro aktuální request tak, aby aktualizovaný snippet měl k dispozici aktualizované hodnoty v $user->identity->data[]. A aby se vyvolal wakeup musí dojít k redirect (předpokládám), čili dokud budu na stránce se snippety, identita bude stále původní, i když už jsem si změnil jméno, …
Nette zjevně chrání session a při jakékoli změně identity i např. při volání $this->user->getStorage()->saveAuthentication($updatedIdentity); dojde je změně id session. Z bezpečnostního hlediska asi dobrá vlastnost, takže bych se jí nerad zbavil nějakým vypnutím v config (pokud to vůbec lze).
Napadá mě po různých pokusech jen řešení si uložit do session nějaký příznak „updateIdentityOnWakeup = true“ a ve fci wakeupIdentity() provest aktualizaci z DB pouze v tomto případě. Změnu pro aktuální request řešit hackem:
// Ruční přepis identity pro aktuální request (paměť)
$reflection = new \ReflectionProperty($this->user, 'identity');
$reflection->setAccessible(true);
$reflection->setValue($this->user, $updatedIdentity);
Ale je to asi trochu fuj řešení.
- Kamil Valenta
- Člen | 833
fulda napsal(a):
Jednak asi nechci, aby to neustále při každém requestu updatovalo identitu z DB
To přece nemusí, jednotlivé updaty z formuláře si můžeš uložit do sessiony. WakeupIdentity se pak do sessiony jen podívá, zda tam nejsou „odloženy“ nějaké aktualizace od posledního login().
- fulda
- Člen | 3
Jasně, to je samozřejmě pravda.
Zdá se, že vykrystalizovalo životaschopné řešení v podobě uložení změněné části identity do session a k tomu příznak, že nastala změna identity od posledního login. Pak, při každém wakeupIdentity, je zkontrolován příznak a pokud je změna, se upraví identita daty uloženými v session. Zdá se, že funkční.
Díky za nasměrování.
Jiné řešení, aniž by došlo ke změněně session po updatu identity a tímpádem znefunkčnění snippetů, se mi nepodařilo najít.