Overovani uzivatele pri kazdem pristupu
- George
- Člen | 8
Zdravim,
s Nette zacinam a placam se v nem asi tyden. Podle Quickstartu a prirucky
uz jsem neco spachal a udelal jsem i autentizaci. Bohuzel to co jsem podle
dokumentace spachal ma zasadni nedostatek a sice, ze se uzivatel overi jen pri
prihlaseni a pak uz ne. Takze pokud se po jeho prihlaseni cokoliv v db zmeni
(heslo, datum platnosti uctu, admin ho zablokuje), tak uzivatel zustava
prihlaseny.
Resim vlastne uplne stejny problem jako v 4 roky starem, jiz uzamcenem vlakne,
kde ale nevzeslo zadne ciste reseni https://forum.nette.org/…dem-pristupu
Nebo aspon ja ho z toho nevycetl ;)
Diky za nakopnuti.
- ZZromanZZ
- Člen | 87
Identita je v session, a pokud bys chtěl ověřovat práva nebo existenci
uživatele musíš šahat do db při každém požadavku.
Viz třeba tohle vlákno
- David Matějka
- Moderator | 6445
abys mel porad aktualni identitu, staci par veci: upravit UserStorage (resp.
metodu getIdentity) a vytvorit si vlastni tridu pro identitu, inspirace jak to
pouzivam ja:
UserStorage.php
<?php
class UserStorage extends \Nette\Http\UserStorage
{
protected $userDao;
public function __construct(\Nette\Http\Session $session,
\Models\UserDao $userDao)
{
parent::__construct($session);
$this->userDao = $userDao;
}
public function getIdentity()
{
$id = parent::getIdentity();
if ($id and $id instanceof Identity and !$id->isLoaded()) {
$this->userDao->loadIdentity($id);
}
return $id;
}
}
Identity.php
<?php
class Identity extends \Nette\Object implements \Nette\Security\IIdentity{
protected $id;
protected $loaded = false;
protected $roles = array();
protected $username;
protected $email;
.....
public function __construct($id){
$this->id = $id;
}
public function __sleep(){
return array("id");
}
public function __wakeup(){
$this->loaded = false;
}
public function isLoaded(){
return $this->loaded;
}
//...gettery, settery
}
userdao uz je potom nejakej tvuj model, kterej bude mit metodu loadIdentity a postara se o jeji nacteni
pak budes muset nastavit tenhle UserStorage jako sluzbu (prepsat defaultni userstorage). ted nevim, jestli to jde v neonu, kdyztak takhle:
services:
nette.userStorage: UserStorage
jinak pres compiler extension
$builder->removeDefinition("nette.userStorage");
$builder->addDefinition($this->prefix("userStorage"))
->setClass("UserStorage");
- George
- Člen | 8
Tak jsem to zatim nejak zbastlil (urcite uplne spatne co se filozofie Nette
tyce ) :)
Casem snad do Nette vice proniknu, zjistim, ze jsem to udelal uplne spatne a
udelam to jinak.
Ted to ale funguje.
Samozrejme uvitam pokud nekdo poradi neco lepsiho, ale nevim jestli to aktualne
pochopim :)
V modelu Authenticator.php jsem vyrobil funkci
<?php
.....
public function isIdentityValid(\Nette\Security\IIdentity $identity)
{
$userData = $this->database->table('users')->where('id', $identity->getId())->fetch();
if ($userData &&
$userData->username == $identity->username &&
$userData->password == $identity->password &&
$userData->disabled == $identity->disabled &&
$userData->role == $identity->role)
{
return TRUE;
} else {
return FALSE;
}
}
?>
a volam ji z BasePresenteru, ktery vypada takto:
<?php
use Nette\Security\User;
/**
* Base presenter for all application presenters.
*/
abstract class BasePresenter extends Nette\Application\UI\Presenter
{
/** @var Authenticator */
private $auth;
public function inject(Authenticator $auth)
{
$this->auth = $auth;
}
protected function startup()
{
parent::startup();
if ($this->name != 'Sign') {
if ($this->getUser()->isLoggedIn()) {
$this->checkUserIdentity();
}
if (!$this->getUser()->isLoggedIn() && $this->getUser()->getLogoutReason() === User::INACTIVITY) {
$this->flashMessage('Došlo k odhlášení z důvodu neaktivity.');
}
if (!$this->getUser()->isLoggedIn()) {
$this->redirect('Sign:in', array('backlink' => $this->storeRequest()));
}
}
}
public function checkUserIdentity()
{
if (!$this->auth->isIdentityValid($this->getUser()->getIdentity())) {
$this->handleSignOut('Nesouhlasí identita uživatele. Přihlašte se prosím znovu.','error');
}
}
public function handleSignOut($msg = 'Odhlášení bylo úspěšné.', $type = 'success')
{
$this->getUser()->logout(TRUE);
if ($msg) { $this->flashMessage($msg,$type); }
$this->redirect('Sign:in', array('backlink' => $this->storeRequest()));
}
}
?>