Automatické přihlášení po registraci
- neznamy_uzivatel
- Člen | 115
Zdravím,
používám standardní usermanager z nette.
Funkci add mám upravenou aby mi brala věci z pole (předávám celý Form)
<?php
public function add($values) {
$values['password'] = self::hashPassword($values['password']);
$values['registered'] = time();
$this->database->table(self::TABLE_NAME)->insert($values);
}
?>
V presenteru provádím registraci uživatele:
<?php
...
/** @var \Model\UserManager @inject */
public $userManager;
public function renderDefault() {
$values['username'] = "pepa";
$values['password'] = "12345678";
$this->userManager->add($values);
...
?>
Chtěl bych, aby byl uživatel ihned přihlášený, takže jsem jen přidal login:
<?php
public function renderDefault() {
$values['username'] = "pepa";
$values['password'] = "12345678";
$this->userManager->add($values);
$user->login($values['username'], $values['password']);
...
?>
na to mi nette bohužel řekne:
Nette\Security\AuthenticationException #2
Uživatelské jméno, nebo heslo je neplatné
Přitom ale ten uživatel se vloží správně, manuální přihlášení funguje.
Jak to tedy prosím zprovoznit?
// Potřebuji to bez redirectu, ta funkce pak dál pokračuje ve zpracování
formu a potřebuji tam už pracovat s ID nového uživatele…
Díky :)
ps. hledám způsob snadný a rychlý, ne nutně „čistý“
// edit:
$user tam mám na začátku: $user = $this->getUser();
Editoval neznamy_uzivatel (12. 6. 2014 14:59)
- Jiří Nápravník
- Člen | 710
Nevím jaký nettí UserManager máš na mysli. Nicméně nebude problém v tom, že u té registrace (v add()) hashujes heslo a u loginu jsi na hashovani zapomnel?
- neznamy_uzivatel
- Člen | 115
Tim to nebude. volani toho loginu je uplne stejne v presenteru kde se
prihlasuju rucne a tam to funguje.
je to model UserManager.php + signPresenterzhe sandboxu
- neznamy_uzivatel
- Člen | 115
Tohle nemam ja v usermanageru. login je funkce v Nette\Security\User
<?php
/********************* Authentication ****************d*g**/
/**
* Conducts the authentication process. Parameters are optional.
* @param mixed optional parameter (e.g. username or IIdentity)
* @param mixed optional parameter (e.g. password)
* @return void
* @throws AuthenticationException if authentication was not successful
*/
public function login($id = NULL, $password = NULL)
{
$this->logout(TRUE);
if (!$id instanceof IIdentity) {
$id = $this->getAuthenticator()->authenticate(func_get_args());
}
$this->storage->setIdentity($id);
$this->storage->setAuthenticated(TRUE);
$this->onLoggedIn($this);
}
?>
To pak vola authenticate v modelu UserManager
<?php
/**
* Performs an authentication.
* @return Nette\Security\Identity
* @throws Nette\Security\AuthenticationException
*/
public function authenticate(array $credentials)
{
list($username, $password) = $credentials;
$row = $this->database->table(self::TABLE_NAME)->where(self::COLUMN_NAME, $username)->fetch();
if (!$row) {
throw new Nette\Security\AuthenticationException('Uživatelské jméno, nebo heslo je neplatné. IDENTITY_NOT_FOUND', self::IDENTITY_NOT_FOUND);
} elseif (!self::verifyPassword($password, $row[self::COLUMN_PASSWORD])) {
throw new Nette\Security\AuthenticationException('Uživatelské jméno, nebo heslo je neplatné. INVALID_CREDENTIAL ', self::INVALID_CREDENTIAL);
} elseif (PHP_VERSION_ID >= 50307 && substr($row[self::COLUMN_PASSWORD], 0, 3) === '$2a') {
$row->update(array(
self::COLUMN_PASSWORD => self::hashPassword($password),
));
}
$arr = $row->toArray();
unset($arr[self::COLUMN_PASSWORD]);
return new Nette\Security\Identity($row[self::COLUMN_ID], $row[self::COLUMN_ROLE], $arr);
}
?>
Zastavi se to na INVALID_CREDENTIAL, pritom ale po rediru to pak uz z jineho presenteru (sign:in, sandbox) normalne prihlasi temi stejnymi udaji.
- thunderbuff
- Člen | 164
Zkus na začátek metody authenticate na chvíli přidat dump($credentials); die();, uvidíš, zda té metodě opravdu posíláš správná data.
- Filip Procházka
- Moderator | 4668
Stačí aby tvůj manager vracel idčko, nebo vložený řádek
$newlyCreatedUser = $this->userManager->add($values);
$data = $newlyCreatedUser->toArray();
unset($data['password']);
$this->user->login(new Identity($newlyCreatedUser->id, $newlyCreatedUser->role, $data));
Do login metody jde totiž předat i instance identity a pak nepotřebuješ heslo.
- neznamy_uzivatel
- Člen | 115
Data posílám správně, zž jsem to takhle porovnával..
Když jsem to změnil za kód:
<?php
$newlyCreatedUser = $this->userManager->add($values);
$data = (array) $newlyCreatedUser;
unset($data['password']);
$this->user->login(new \Nette\Security\Identity($newlyCreatedUser->id, $newlyCreatedUser->role, $data));
?>
tak výsledek:
PDOException
You cannot serialize or unserialize PDO instances
z add jsem zkoušel vracet jak celý řádek, tak jen pole s id a role. Obojí dělá tu stejnou chybu :(
edit:
Tak ta chyba uz je tam „naporad“ i po smazani cache. Otevru hlavni
stranku – jiny presenter nez se registrovalo a okamzite konec:
<?php
public function initialize() {
Nette\Caching\Storages\FileStorage::$useDirectories = TRUE;
$this->getByType("Nette\Http\Session")->exists() && $this->getByType("Nette\Http\Session")->start();
...
?>
Ten treti radek dela tu chybu, ale predtim to bylo na radku s login($…)
Tak zase edit: Chybu uz to nedela, zustalo to v session, pomohlo smazani cookies. Nicmene ten login bohuzel nejede :(
Editoval neznamy_uzivatel (13. 6. 2014 13:57)
- Filip Procházka
- Moderator | 4668
Vždyť to máš o pár příspěvků výš napsané jak to máš udělat, dokonce jsi sem ten kód sám kopíroval. Řádek z Nette\Database nemůžeš přetypovávat na array, nekopíruj kód, přemýšlej nad ním
Svůj předchozí příspěvek jsem opravil, aby fungoval pokud vracíš tu instanci toho row.
- neznamy_uzivatel
- Člen | 115
OK, diky, tohle funguje.
To pole jsem pochopil, proto jsem psal, ze jsem zkousel vracet z add() pole
i row.
Proto mi ted neni jasne z jakeho duvodu mi to nefungovalo hned, kdyz jsem
z add() vratil pole
return array(‚id‘ ⇒ $row->id, ‚role‘ ⇒ $row->role);