Chyba při přihlašování do administrace
- Hitny14
- Člen | 90
Ahoj, mám v nette dva moduly a u každého řeším samostatné přihlašování. Při přihlášení mi laděnka vrátí chybu Authenticator has not been set. myslím si že mám chybu někde v configu tak bych se chtěl zeptat jak na to.
Authenticator:
public function authenticate(array $credentials)
{
list($email, $password) = $credentials;
$user = $this->usersManagerAdmin->findOneBy(['username' => $email]);
if (!$user) {
throw new AuthenticationException('Byl zadaný špatný e-mail.', self::IDENTITY_NOT_FOUND);
} elseif (!Passwords::verify($password, $user->password)) {
throw new AuthenticationException('Bylo zadané špatné heslo..', self::INVALID_CREDENTIAL);
} elseif (Passwords::needsRehash($user->password)) {
$user->setPassword(Passwords::hash($password));
$this->em->persist($email);
$this->em->flush();
}
return $user;
}
Přihlašovací presenter:
public function proccessLogIn(Form $form, $values)
{
$user = $this->getUser();
$user->getStorage()->setNamespace('Admin');
$user->login($values->email, $values->password);
$this->redirect('Admin:Homepage:login');
$this->flashMessage('Vítejte v administraci '.$_SERVER['HTTP_HOST'], 'success');
}
BassePresenter:
public function getUser() {
$user = parent::getUser();
$user->getStorage()->setNamespace('Admin');
return $user;
}
a config:
services:
- App\AdminModule\Model\Security\UsersManagerAdmin
adminAuthenticator:
class: App\AdminModule\Model\Security\AdminAuthenticator
autowired: no
Díky za každou ranu už si stím fakt nevím rady..
- Aurielle
- Člen | 1281
Budeš si muset authenticator v přihlašovacím presenteru ručně
vytáhnout z kontejneru (teoreticky by mohl jít i injectnout, vyzkoušej,
nemám otestované) a nastavit
do Usera, nebo zrušit příznak autowired: no
. Což ale
předpokládám nechceš, protože máš pravděpodobně
authenticatory dva.
- Unlink
- Člen | 298
Určite nič nevyťahuj z contextu, radšej si ho tam injectni
Prihlasovací presenter
function __construct(AdminAuthenticator $authentificator) {
$this->authentificator = $authentificator;
}
public function proccessLogIn(Form $form, $values)
{
$user = $this->getUser();
$user->setAuthenticator($this->authentificator); //Nastaviť ho userovi
$user->getStorage()->setNamespace('Admin');
$user->login($values->email, $values->password);
$this->redirect('Admin:Homepage:login');
$this->flashMessage('Vítejte v administraci '.$_SERVER['HTTP_HOST'], 'success');
}
A potom si ten presenter zaregistruj v configu, aby si mu vedel predať ten authentificator
services:
- App\Moj\Login\Presenter(@App\AdminModule\Model\Security\AdminAuthenticator)
- Jan Suchánek
- Člen | 404
@Unlink: a co takhle?
function __construct(AdminUserManager $adminUserManager) {
$this->adminUserManager = $adminUserManager;
}
public function proccessLogIn(Form $form, $values)
{
// $user = $this->getUser(); // Nepotřebuju, o usera se stará manager.
// $user->setAuthenticator($this->authenticator); // Service dostane authenticator
// $user->getStorage()->setNamespace('Admin'); Service se stará o namespace, nebo možná by stačil jen ten authenticator
try {
$this->adminUserManager->login($values->email, $values->password);
$this->flashMessage('Vítejte v administraci!', 'success'); // fujky $_SERVER['HTTP_HOST'] na to používáme něco jiného ne?
} catch(Nette\Security\AuthenticationException $e){ // použít vlastní excepiton nebo Nette\Security\AuthenticationException
$form->addError($e->getMessage()); // buď vypsat co se stalo případně si napsat vlastní chybu
return;
}
$this->restoreRequest($this->backlink);
$this->redirect('Admin:Homepage:');
}
převzato z CD-collection.
Editoval jenicek (2. 6. 2015 13:03)
- David Matějka
- Moderator | 6445
@jenicek v cd-collection se vola login na
Nette\Security\User
a to pak zavola authenticator
tri rozumny moznosti, co me napadaji:
- to, jak to pise @Unlink
Nette\Security\User::login
muze rovnou akceptovat jako parametr identitu, takze pujde i
$identity = $this->adminUserManager->authenticate(array($email, $password));
$this->user->login($identity);
to by se nechalo pak trochu refaktorovat, ze by pouziti vypadalo ± tak, jak
pise @jenicek
3. trochu slozitejsi, ale nejhezci :) Vytvoris si jeste jeden authenticator,
ktery bude routovat pozadavky na konkretni authenticatory dle nastavenyho
namespace na user storage. Tenhle princip pouzivam v librette/security-namespaces,
zjednodusene by to mohlo vypadat nejak takto:
class AuthenticatorRouter extends Nette\Object implements Nette\Security\IAuthenticator
{
private $authenticators = [];
private $userStorage;
public function __construct(Nette\Security\IUserStorage $userStorage)
{
$this->userStorage = $userStorage;
}
public function add($namespace, Nette\Security\IAuthenticator $authenticator)
{
$this->authenticators[$namespace] = $authenticator;
}
public function authenticate(array $credentials)
{
$ns = $this->userStorage->getNamespace();
if (!isset($this->authenticators[$ns])) {
throw new \Exception;
}
return $this->authenticators[$ns]->authenticatoe($credentials);
}
}
services:
frontAuthenticator: {class: FrontAuthenticator, autowired: false}
adminAuthenticator: {class: AdminAuthenticator, autowired: false}
authenticator:
class: AuthenticatorRouter
setup:
- add(Admin, @adminAuthenticator)
- add(Front, @frontAuthenticator)
v sign presenteru pak staci nastavit spravny NS na user storage a pojede to :)
- Jan Suchánek
- Člen | 404
@David Matějka za mě tam chyběl blok try, a ukončení v případě chyby, navíc by to furt vítalo.
A $_SERVER[‚HTTP_HOST‘] tam fakt patří?
Editoval jenicek (2. 6. 2015 14:29)
- Hitny14
- Člen | 90
Díky všem za odpovědi. Použil sem příklad od @Unlink a při nastavení v configu:
services:
- App\AdminModule\Model\Security\UsersManagerAdmin
- App\AdminModule\Presenters\Homepage\HomepagePresenter(@App\AdminModule\Model\Security\AdminAuthenticator)
adminAuthenticator:
class: App\AdminModule\Model\Security\AdminAuthenticator
autowired: no
Mi to hlási chybu:
Class App\AdminModule\Presenters\Homepage\HomepagePresenter used in
service ‚78_App_AdminModule_Presenters_Homepage_HomepagePresenter‘ not found
or is not instantiable.
Přihlašování používám v HomepagePresenteru.
@DavidMatějka ještě bych se chtěl prosím tě zeptat kdybych chtěl použít ten tvůj třetí způsob kam bych mel dát ten AuthenticatorRouter? Do App/Models/Security a nebo do App/AdminModule/Models/Security
- Hitny14
- Člen | 90
@DavidMatějka chtěl sem zkusit ten tvůj třetí způsob a laděnak
mi hlási chybu že authenticator nebyl nalezen.
Class App\Model\Security\Authenticator used in service
‚authenticator‘ not found or is not instantiable.
Takhle vypadá můj authenticator:
<?php
namespace App\Model\Security;
use Nette\Object;
use Nette\Security\IAuthenticator;
/**
* Class Authenticator
* @package App\Model\Security
*/
abstract class Authenticator extends Object implements IAuthenticator
{
private $authenticators = [];
private $userStorage;
public function __construct(Nette\Security\IUserStorage $userStorage) {
$this->userStorage = $userStorage;
}
public function add($namespace, Nette\Security\IAuthenticator $authenticator) {
$this->authenticators[$namespace] = $authenticator;
}
public function authenticator(array $credentials) {
$ns = $this->userStorage->getNamespace();
if(!isset($this->authenticators[$ns])) {
throw new \Exception;
}
return $this->authenticators[$ns]->authenticate($credentials);
}
}
Začínám i s doctrínou je to možná použiti i pro doctrinu?
A můj config:
- App\Model\Security\Users
frontAuthenticator: {class: App\Model\Security\FrontAuthenticator, autowired: false}
adminAuthenticator: {class: App\AdminModule\Model\Security\AdminAuthenticator, autowired: false}
authenticator:
class: App\Model\Security\Authenticator
setup:
- add(Admin, @adminAuthenticator)
- add(Front, @frontAuthenticator)
- David Matějka
- Moderator | 6445
ta trida nema byt abstraktni (a ta metoda ma byt authenticate a ne authenticator)
- Hitny14
- Člen | 90
Moje chyba špatně sem si toho všiml. Všechno je v pohodě ale jen když
se chci přihlásit. Tak mě laděnka vyzívá k definování metody
Call to undefined method
App\AdminModule\Model\Security\AdminAuthenticator::authenticator()
To nestačí když mám v configu:
frontAuthenticator: {class: App\Model\Security\FrontAuthenticator, autowired: false}
adminAuthenticator: {class: App\AdminModule\Model\Security\AdminAuthenticator, autowired: false}
authenticator:
class: App\Model\Security\AuthenticatorRoute
setup:
- add(Admin, @adminAuthenticator)
- add(Front, @frontAuthenticator)
- Hitny14
- Člen | 90
Chyba opravena.
public function authenticator(array $credentials) {
$ns = $this->userStorage->getNamespace();
if(!isset($this->authenticators[$ns])) {
throw new \Exception;
}
return $this->authenticators[$ns]->authenticator($credentials);
}
v části
return $this->authenticators[$ns]->authenticator($credentials);
má být:
return $this->authenticators[$ns]->authenticate($credentials);