Authenticator s dibi přes modelLoader
- Jack06
- Člen | 168
Zdravím, mám takový problém. Používám dibi a pro jednodušší
připojování k tabulkám jsem použil model loader viz:
https://pla.nette.org/…cy-injection
Vytvořil jsem si class na registrační formulář a chci aby se po
úspěšné registraci uživatel automaticky přihlásil. Jenže nevím, jak se
dostat k autentizaci. Kvůli dibi jsem si hodil i požadovaný namespace nad
třídu Authenticator. Zkoušel jsem to dosti způsoby, ale u základního mi
to háže:
Cannot instantiate service, class ‚Models\Authenticator‘ not found.
Když se k tomu připojím pomocí getModel, tak mi to zase cpe, že metoda getUser neexistuje.
RegistrationForm
<?php
namespace FrontModule\Forms;
use Nette\Application\UI\Form,
Nette\InvalidStateException,
Nette\Security as NS;
class RegistrationForm extends Form {
public function __construct($parent = null, $name = null) {
parent::__construct($parent, $name);
$this->addProtection('Prosím pdešlete formulář znovu (vypršela platnost bezpečnostního tokenu).');
$this->addText('email', 'Email:')
->addRule(Form::FILLED, 'Prosím zadejte registrační email')
->addRule(Form::EMAIL, 'Zadaný email je neplatný');
$this->addSubmit('send', 'Zaregistrovat se');
$this->onSuccess[] = array($this, 'submitted');
}
public function submitted(Form $form) {
try {
$values = $form->values;
$values['ip'] = $this->presenter->getService('httpRequest')->getRemoteAddress();
$values['regdate'] = new \Nette\Datetime;
$values['salt'] = $this->presenter->context->params['salt'];
$password = $this->presenter->getModel('user')->userCreate($values);
$this->presenter->getUser()->setExpiration('+ 20 minutes', TRUE);
$this->presenter->getUser()->login($values->email, $password);
$this->presenter->flashMessage('Účet byl úspěšně vytvořen a vy úspěšně přihlášeni', 'success');
$this->presenter->redirect('Homepage:');
} catch (InvalidStateException $e) {
$this->presenter->flashMessage($e->getMessage(), 'warning');
$this->presenter->redirect('this');
}
}
}
Authenticator
<?php
namespace Model;
use Nette\Security as NS;
class Authenticator extends \Nette\Object implements NS\IAuthenticator {
/** @var DibiConnection */
private $db;
public function __construct($connection, $config) {
$this->db = $connection;
}
/**
* Performs an authentication
* @param array
* @return Nette\Security\Identity
* @throws Nette\Security\AuthenticationException
*/
public function authenticate(array $credentials) {
list($email, $password) = $credentials;
$row = $this->db
->select('*')
->from('user')
->where('email', $email)
->fetch();
if (!$row || ($row->password !== $this->calculateHash($password))) {
throw new NS\AuthenticationException("Uživatel '$email' nebyl nalezen.", self::IDENTITY_NOT_FOUND);
}
unset($row->password);
return new NS\Identity($row->id, $row->role, $row->toArray());
}
/**
* Computes salted password hash.
* @param string
* @return string
*/
public function calculateHash($password) {
return hash('sha256', $password . $this->context->params['salt']);
}
}
Děkuji za rady
- Jack06
- Člen | 168
Ok fajne, překlep v configu byl, nicméně teď to hodí:
Missing argument 1 for Model\Authenticator::__construct(), called in C:\xampp\htdocs\zapisto\libs\Nette\DI\ServiceBuilder.php on line 49 and defined
u constructu na dibi, nevím jak, ale asi to bude potřeba prohnat tim modelLoaderem. Jako DI je pro mě celkem novinka, takže se v tom učím a fakt netuším jestli se to dá nastavit i nějak v neonu, nebo ne.
- Jack06
- Člen | 168
common:
php: # PHP configuration
date.timezone: Europe/Prague
# session.save_path: "%tempDir%/sessions"
# zlib.output_compression: yes
database:
hostname: 127.0.0.1
username: root
password:
database: db_xx
persistent: true
charset: utf8
lazy: true
services:
robotLoader:
run: true
authenticator:
Model\Authenticator
modelLoader:
factory: ModelLoader::factory
variables:
salt: xxx
production < common:
development < common:
console < common:
- umrlec
- Člen | 56
Zkus to takto …
config
common:
php: # PHP configuration
date.timezone: Europe/Prague
# session.save_path: "%tempDir%/sessions"
# zlib.output_compression: yes
services:
robotLoader:
run: true
modelLoader:
factory: ModelLoader::factory
authenticator:
class: Model\Authenticator
arguments: ["@database"]
database:
class: DibiConnection
arguments: [ {
hostname: 127.0.0.1
username: root
password: ''
database: db_xx
persistent: true
charset: utf8
lazy: true
} ]
variables:
salt: xxx
production < common:
development < common:
console < common:
A v konstruktoru Authenticatoru si smaž ten druhý parametr
- Jack06
- Člen | 168
No, tím ale nebude fungovat modelLoader, respektive toto:
class ModelLoader {
private $connection;
private $config;
public static function factory(Nette\DI\Container $container) {
$config = $container->params['database']; // toto
$db = dibi::connect($config);
return new self($db, $config);
}
public function __construct($connection, $config) {
$this->connection = $connection;
$this->config = $config;
}
public function loadModel($modelName) {
$class = "Model\\$modelName";
return new $class($this->connection, $this->config);
}
}
- vranacik
- Člen | 9
a čo schovávaš do $config?, nie je ten parameter zbytočný? Inač som si prvý krát prešiel odkaz, ktorý máš v prvom poste a je to tam celkom slušne vysvetlené a umrlec ti radí tiež dobre.
ak v $config prenášaš konfiguráciu pre pripojenie k DB tak načo to máš aj v neone? Presiel som si to tri krát a nejak som tomu nepochopil (tomu tvojmu kodu)
//ziskavaš z kontainera, tak načo ho potrebuješ pchať aj do konštruktora?
$config = $container->params['database'];
//v kontajneri tie dáta najdeš vždy
...
//a vo factory by potom malo stačiť vrátiť len spojenie, teda:
return $db
- Jack06
- Člen | 168
Ten ModelLoader mi byl takto nahozen, už nevím kdo mi to poslal, nicméně jelikož jsem nechápal jak s tím DI ruku v ruce pracovat, tak jsem to prostě použil tak, jak mi to někdo napsal. Ano ten parametr je zbytečný. Bylo mi posláno již funkční řešení. Pokud by měl někdo stejný problém, tak: https://gist.github.com/1076590