Prázdná stránka po odeslání formuláře
- cuga
- Člen | 210
Mám klasický přihlašovací formulář (vykopírovaný ze skeletonu ;))
Na localhostu vše v pohodě, v případě, že zadám neplatnou kombinaci uživatelského jména a hesla, odchytí se vyjímka, která se vypíše jako chyba formuláře.
Problém nastává na produkčním serveru. Správná kombinace, uživatel se přihlásí, vše je v pořádku, v případě špatné kombinace se mi místo chyby zobrazí bílá obrazovka (ve FF) nebo mě rovnou dořve, že „Tato stránka není dostupná“ (v Chrome).
Hlavičky odpovědi serveru se tváří, že 200 OK a šlus. Žádný error log, nic.
Hosting je Savana, všechny přesměrování fungují bez problémů. Přihlašování nefunguje správně ani u administrace.
Napadá někoho kde může být zakopán pes?
Nette je aktuální neprefixovaná verze pro PHP 5.2
Editoval cuga (7. 10. 2010 3:45)
- srigi
- Nette Blogger | 558
Pri nespravnom mene/hesle si musis chytat vynimky
AuthenticationException
, inak ti na produkcii prebubla az na
ErrorPresenter a ten (po novom – Nette 2) vykresli 500-ku. Osetruj to
cca takto:
public function formSubmitted($form)
{
try {
$user = Environment::getUser();
$user->login($form['login']->value, $form['password']->value);
$this->getPresenter()
->getApplication()
->restoreRequest($this->getPresenter()->backlink);
$this->getPresenter()->redirect('Dashboard:default');
} catch (AuthenticationException $e) {
$form->addError($e->getMessage());
}
}
- cuga
- Člen | 210
tohle sem tak nejak uz od zacatku co pracuju s nette odkoukal v examples, a duvod to zrejme nebude, protoze by se mi to probublalo i na localhostu, nebo se mylim?
ad srigi: $this->getPresenter()->getApplication(), nestacilo by jenom $this->getApplication(), protoze presenter mas v $this?
Editoval cuga (7. 10. 2010 12:10)
- cuga
- Člen | 210
v UsersModel.php mam klasicke
<?php
...
public function authenticate(array $credentials)
{
$login = $credentials[self::USERNAME];
$row = $this->findByLogin($login);
if(!$row) {
throw new AuthenticationException("Chybně zadané uživatelské jméno nebo heslo.", self::IDENTITY_NOT_FOUND);
}
$config = Environment::getConfig('security');
$password = hash_hmac('sha256', $credentials[self::PASSWORD] . $row->salt , $config->hmacKey);
if($row->heslo !== $password) {
throw new AuthenticationException("Chybně zadané uživatelské jméno nebo heslo.", self::INVALID_CREDENTIAL);
}
$this->update($row->id, array('lastLogin' => time()));
unset($row->heslo);
return new Identity($row->jmeno . " " . $row->prijmeni, $row->role, $row);
}
...
?>
vsude jinde to funguje, tak problem nebude, na Savane nefunguje ani ciste CD-collection.
- Aurielle
- Člen | 1281
Pamatuji si, že se mi to podařilo „obs*at“ celkem dost neobvyklým způsobem, tzn. vytvořením SavanaAuthanticatoru a FailedIdentity. (kódy jsou ze Nette 0.8.x-0.9.x, takže jsou trošku kostrbaté :D)
SavanaAuthenticator:
class SavanaAuthenticator extends RSWAuthenticator
{
const BAD_PASSWORD = 5;
const USER_INACTIVE = 6;
const USER_BANNED = 7;
/**
* Authenticate user
* @param array $credentials
* @return Identity
* @throws AuthenticationException
*/
public function authenticate(array $credentials)
{
// Get the credentials
$username = $credentials[self::USERNAME];
$password = $credentials[self::PASSWORD];
// Defined roles
$role = array(
self::USER => 'user',
self::EDITOR => 'editor',
self::ADMINISTRATOR => 'administrator',
);
// If any of required credentials is empty, throw exception
if(empty($username) || empty($password))
{
return new FailedIdentity(self::INVALID_CREDENTIAL);
}
// Get user by username
try
{
$userdata = RSWUser::get($username, RSWUser::USERNAME);
}
catch(UserNotFoundException $e)
{
return new FailedIdentity(self::IDENTITY_NOT_FOUND);
}
// Hash the password and compare it
$password = RSWUser::createHash($password, $userdata->username . $userdata->user_email);
if($password !== $userdata->user_password)
{
return new FailedIdentity(self::BAD_PASSWORD);
}
// User is inactive...
if(self::INACTIVE === (int) $userdata->user_active)
{
return new FailedIdentity(self::USER_INACTIVE);
}
// or banned...
if(self::BANNED === (int) $userdata->user_active)
{
return new FailedIdentity(self::USER_BANNED);
}
// Assign role
$role = $role[$userdata->user_type];
// Update lastvisit
dibi::query('UPDATE [users] SET [user_lastvisit] = %i WHERE [user_id] = %i', time(), $userdata->user_id);
$userdata->user_lastvisit = time();
// Return identity
return new Identity($userdata->username, $role, $userdata);
}
}
a následné ověřování při přihlašování uživatele:
if($user->getAuthenticationHandler() instanceof SavanaAuthenticator)
{
// Bugfixed code for Savana production server using SavanaAuthenticator
$user->authenticate($values['username'], $values['password']);
$identity = $user->getIdentity();
if($identity instanceof FailedIdentity)
{
$user->signOut(TRUE);
$this->redirect(303, 'User:login');
}
}
Toto řešení funguje protože v žádném případě nevyhodí výjimku, ale je poněkud nečisté. FailedIdentity je potomek Identity a u mě v podstatě zajišťoval jen flashMessage do presenteru podle předaného příznaku.
- David Grudl
- Nette Core | 8229
Budu rád, když přidáte zkušenost na https://forum.nette.org/…gu-blacklist?…