Ke starsimu tematu „zamezení vícenásobného přihlášení jednoho uživatele“

Upozornění: Tohle vlákno je hodně staré a informace nemusí být platné pro současné Nette.
Willik
Člen | 19
+
0
-

Prochazel jsem starsi prispevky na tema „zamezení vícenásobného přihlášení jednoho uživatele“ (Zde) a na konci debaty se tam k reseni pres UserStorage od enumag objevilo upozorneni na opakovane dotazy do db. Podle zdrojaku pricinou bude volani getIdentity() kdekoli, napr. v presenteru . Pri kazdem volani getIdentity() dojde k volani getSessionSection() a tedy i kontrole validity identity. Pokud probiha kontrola proti db, dochazi k opakovanym dotazum.

Muj dotaz tedy je, jestli neni nejake nove reseni, pripadne jake reseni je nejvhodnejsi (napr. v startupu presenteru nacist potrebne parametry do pole a to pak pouzit ke kontrole validity identity).

Dekuju.

Tharos
Člen | 1030
+
+1
-

Neprocházel jsem odkazovaný kód, ale myslím, že kontextu rozumím.

Věřím, že není vůbec žádný problém zajistit, aby se potřebný dotaz do db položil jen jednou za request. Stačí si jen po první kontrole vhodně uchovat informaci (například v nějaké privátní property nějaké služby), že kontrola již proběhla, a dále ji už neprovádět.

Dále bych to nesvazoval s žádnou startup metodou, nýbrž bych to provedl lazy způsobem v momentě, kdy se s přihlášením poprvé pracuje.

Pro lepší představu bych to pojal podobně jako lazy connection do databáze: připojení se vytvoří jen jednou (uvažujme běžnou aplikaci…) a přesně v okamžiku, kdy je to poprvé zapotřebí.

Editoval Tharos (14. 10. 2016 14:49)

Willik
Člen | 19
+
0
-

Jestli tomu rozumim dobre, tak treba v mem pripade mam jako sluzbu zaregistrovany model UserRepository, ktery pouzivam i v te metode isIdentityValid, tak v nem proste vytvorit property napr. isValidate, kterou pri prvnim volani ve funkci UserStorage::isIdentityValid nastavim , takze k volani isIdentityValid sice bude dochazet, ale podle stavu te property budu/nebudu sahat do db.

Editoval Willik (14. 10. 2016 15:08)

Tharos
Člen | 1030
+
0
-

Přesně tak. :)

Willik
Člen | 19
+
0
-

Dekuju za poradu a konzultaci. :-)

Uz jsem to tak vyresil. Jeste jsem tu kontrolu presunul pred samotne isIdentityValid.

/**
 * Checks if the identity is still valid.
 * @param \Nette\Security\IIdentity $identity
 * @return bool
 */
protected function isIdentityValid(\Nette\Security\IIdentity $identity) {
    $this->userRepository->setIsIdentityValidate(TRUE);
    $entity = $this->userRepository->getUserEntity('id', $identity->id);
    return $entity && intval($identity->role) === intval($entity->role);
    // return true;
}

/**
 * Returns and initializes $this->sessionSection.
 * @param bool $need
 * @return SessionSection
 */
protected function getSessionSection($need) {
    $section = parent::getSessionSection($need);
    if ($section->authenticated && $section->identity instanceof \Nette\Security\IIdentity && $this->userRepository->getIsIdentityValidate() === FALSE) {
        if (!$this->isIdentityValid($section->identity)) {
            $section->authenticated = FALSE;
            $section->reason = self::IDENTITY_CHANGED;
            if ($section->expireIdentity) {
                unset($section->identity);
            }
            unset($section->expireTime, $section->expireDelta, $section->expireIdentity, $section->expireBrowser, $section->browserCheck, $section->authTime);

            $this->userRepository->setIsIdentityValidate(FALSE);
        }
    }
    return $section;
}

Editoval Willik (14. 10. 2016 16:41)