Authentificator a DB, pomoc do začátku
- Merfinder
- Člen | 35
Zdravím, už druhý den se snažím přijít na připojení k DB a authentifikaci. Prošel jsem už tunu topiců a jsem z toho nějakej mimo. Není někde nějaký topic, který fakt popisuje přesně co a jak? Jsem začátečník, tak doufám že ke mě budete shovívaví a odnesu si nějaké moudré rady aby mě to popostrčilo o kus dál.
- CZechBoY
- Člen | 3608
Co konkrétně nechápeš?
Mrkni do sandboxu na ukázkový
autentikátor.
Tu třídu zaregistruješ do konfiguráku
jako službu.
- Merfinder
- Člen | 35
Takže pokud si budu dělat svůj autentifikátor tak ho vytvořím a pak ho musím vložit(registrovat v configu) jako je ten nynější UserManager? A dále nechápu jak propojit tu databázi… přes toho adminera jsem si udělal databázi kde je tabulka user a v ní id,login,password,role, jenže nevím jak jí napojit :/ vím že se to dělá taky v tom configu ale už jsem toho viděl tolik že jsem z toho zmatenej :/
- CZechBoY
- Člen | 3608
Zkus si trochu proklikat ten repozitář sandboxu a třeba ti něco dojde
samo :-)
Do config.local.neon
se ukládá připojení k databázi. Tento soubor se většinou
v repozitářích (git, svn, …) neverzuje, pouze se nahraje základní
varianta jako je v sandboxu. Příklad nastavení viz dokumentace (kousek nad
kapitolou dotazy).
Dále si musíš předat instanci databázové vrstvy
(\Nette\Database\Context
), viz konstruktor
té třídy UserManager.
Editoval CZechBoY (19. 1. 2016 21:33)
- Merfinder
- Člen | 35
Dobře řekněme že ten config.local.neon mám nastavenej(dbname,user,password atd..) tím bych měl mít nastavenou databázi..... a v config.neon je zaregistrovaný autentifikátor(ten základní UserManager) a v něm jsem jen poupravil název tabulky… dále ten autentifikátor tedy obsahuje konstruktor
` public function __construct(\Nette\Database\Context $database)
{
$this->database = $database;
}`
a ten se ještě někam předává? nebo jak?
- CZechBoY
- Člen | 3608
Ten už sis správně uložil do property/soukromé třídní proměnné
$this->database
. Od teď už můžeš v jakékoliv
nestatické (všechny metody bez označení static) metodě
používat $this->database
.
Pokud ta tvoje třída implementuje rozhraní IAuthenticator
tak
se ti sama registruje a bude se používat při loginu uživatele. Viz formulář
pro přihlášení.
// $this->user je instance třídy Nette\Security\User
$this->user->login($jmeno, $heslo);
- Merfinder
- Člen | 35
Takže nemusím toto
` public function __construct(\Nette\Database\Context $database)
{
$this->database = $database;
}`
vkládat do SignPresenter, kde se přihlašuji přes formulář?
v SignPresenteru mám toto
<?php
namespace AdminModule;
use Nette;
class SignPresenter extends BasePresenter
{
protected function beforeRender()
{
parent::beforeRender();
$this->setLayout('layoutLogin');
}
public function renderDefault()
{
}
protected function createComponentSignInForm()
{
$form = new Nette\Application\UI\Form;
$form->addText('username')
->setRequired('Prosím vyplňte své uživatelské jméno.')->setAttribute("placeholder","Uživ. jméno");
$form->addPassword('password')
->setRequired('Prosím vyplňte své heslo.')->setAttribute("placeholder","Heslo");;
$form->addSubmit('send', 'Přihlásit');
$form->onSuccess[] = array($this, 'signInFormSucceeded');
return $form;
}
public function signInFormSucceeded($form)
{
$values = $form->values;
try {
$this->user->login($values->username, $values->password);
$this->redirect('Dashboard:');
} catch (Nette\Security\AuthenticationException $e) {
$form->addError('Nesprávné přihlašovací jméno nebo heslo.');
}
}
public function actionOut()
{
$this->getUser()->logout();
$this->flashMessage('Odhlášení bylo úspěšné.');
$this->redirect('Sign:in');
}
}
Pořád se mi ale nedaří se přihlásit :/ hlásí pořád Nesprávné přihlašovací jméno nebo heslo.
- CZechBoY
- Člen | 3608
Nee, předávej si závislosti jen tam kde je potřebuješ. :-)
Jak máš uložená hesla v databázi? Stejně jako je kontroluješ
potom?
V tom autentikátoru v sandboxu je i metoda
na přidání uživatele add
, která přidá nového
uživatele – obstará zahashování hesla a vyhazuje výjimku pokud uživatel
s tím emailem už existuje.
Editoval CZechBoY (19. 1. 2016 23:25)
- Merfinder
- Člen | 35
Nějak jsem to pošteloval a jde :D …ještě bych si chtěl ujasnit, když vytvářím to připojení k databázi a používám to teda u toho autentifikátoru viz.
/** @var Nette\Database\Context */
public $database;
public function __construct(\Nette\Database\Context $database)
{
$this->database = $database;
}
a pak potřebuju připojení k databázi třeba když vypisuji články, tak co mám použit? znovu ten kód v presenteru s články nebo existuje něco globálního?
- CZechBoY
- Člen | 3608
Predej si to pres konstruktor zase no.
Potom tu tridu muzes podedit aby si nemusel porad ten konstruktor psat.
use Nette\Database\Context;
abstract class BaseDb
{
protected $database;
public function __construct (Context $database)
{
$this->database = $database;
}
}
Potom clankovy repozitar
class ArticleRepository extends BaseDb
{
public function getBySlug ($slug)
{
return $this->database
->table('article')
->where('slug', $slug);
}
}
A do konfiguraku config.neon registrujes pouze ArticleRepository.
Editoval CZechBoY (20. 1. 2016 18:28)
- chemix
- Nette Core | 1310
@Merfinder muzu se zeptat? Zkousel jsi si projit Quick startem? Narazil jsi tam na nejky problem? Nebo vse slo podle planu?
- Merfinder
- Člen | 35
Snažím se vypsat uživatele, ale nedaří se, pokouším se dodržet ten postup co je v quickstartu ale je problém s tou proměnnou $posts jako z quickstrtu…
UserRepository.php
<?php
namespace App\Model;
use Nette,
App\Model;
class UserRepository extends BaseDb
{
public function getUsers()
{
return $this->database->table('users')->order('username DESC');
}
}
UsersPresenter.php
/**
* @var \App\Model\UserRepository
* @inject
*/
public $model;
public function renderDefault()
{
$this->template->users = $this->model->getUsers();
}
template show.latte
<div n:foreach="$users as $user" class="post">
<div class="username">{$user->username}</div>
</div>
config.neon
services:
- App\Forms\SignFormFactory
- App\Model\UserAuth
- App\Model\UserRepository
router: App\RouterFactory::createRouter
problém je s tou proměnnou $users, nechápu co mám dát tam jak je $this->template->????
- Merfinder
- Člen | 35
No stránka se mi zobrazí normálně ale dole Tracy jsou dva errory
- PHP Notice: Undefined variable: users in D:\Programy\XAMPP\htdocs\TestCMS\sandbox\temp\cache\latte\sandbox-app-AdminModule-templates-Users-show-latte-Templated87688856cc8c76359e49b977877a00d.php:23
- PHP Warning: Invalid argument supplied for foreach() in D:\Programy\XAMPP\htdocs\TestCMS\sandbox\temp\cache\latte\sandbox-app-AdminModule-templates-Users-show-latte-Templated87688856cc8c76359e49b977877a00d.php:23
- David Matějka
- Moderator | 6445
Jelikoz volas akci show
, ale plnis to v renderDefault, coz je
pro akci default. takze jen prejmenuj tu metodu na renderShow
- Gl4dr
- Člen | 7
Zdravím, řeším podobný problém. Prošel jsem si důkladně tuto diskuzi a stále mi přihlašování nefunguje. Kontroloval jsem HASH otisky, přístup do databáze i vypsání dat z ní. Mělo by to fungovat, akorát pokaždé po zadání jména a hesla mi to napíše „Nesprávné přihlašovací jméno nebo heslo.“ poradíte mi někdo co s tím dělat? Vše jsem se pokusil nastavit stejně jako v tomto tématu, a mělo by to tak být.
- Gl4dr
- Člen | 7
Tak jsem to uploadnul. Kdyžtak na to koukněte. Asi tam budou nějaký nesmysly, jak jsem testoval.
- Gl4dr
- Člen | 7
Je to sice blbej dotaz, ale jsem docela začátečník. Udělal jsem si stejnej formulář jako je sign in. A když se ho snažím zavolat vyhodí to error Call to a member function add() on null
upravenej kus SignPresenteru
<?php
protected function createComponentRegisterForm()
{
$roles = array(
'comp1' => 'Company 1',
'comp2' => 'Company 2',
'comp3' => 'Company 3',
);
$form = new Nette\Application\UI\Form;
$form->addText('username', 'Username:')
->setRequired('Please enter your username.');
$form->addPassword('password1', 'Password:')
->setRequired('Please enter your password.');
$form->addPassword('password2', 'Password again:')
->setRequired('Please enter your password.');
$form->addRadioList('radio2', 'Select your company:', $roles);
$form->addSubmit('send', 'Register');
//call method registerFormSucceeded() on success
$form->onSuccess[] = $this->registerFormSucceeded;
return $form;
}
public function registerFormSucceeded($form)
{
$values = $form->getValues();
$this->UserManager->add($values->username, $values->password, $values->radio2);
$this->flashMessage('You have been registered succesfuly.');
}
?>
a muj UserManager
<?php
namespace App\Model;
use Nette;
use Nette\Security\Passwords;
/**
* Users management.
*/
class UserManager extends Nette\Object implements Nette\Security\IAuthenticator
{
const
TABLE_NAME = 'uzivatele',
COLUMN_ID = 'ID_Uzivatel',
COLUMN_NAME = 'Jmeno',
COLUMN_PASSWORD_HASH = 'heslo',
COLUMN_ROLE = 'role';
/** @var Nette\Database\Context */
private $database;
public function __construct(Nette\Database\Context $database)
{
$this->database = $database;
}
/**
* 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('The username is incorrect.', self::IDENTITY_NOT_FOUND);
} elseif (!Passwords::verify($password, $row[self::COLUMN_PASSWORD_HASH])) {
throw new Nette\Security\AuthenticationException('The password is incorrect.', self::INVALID_CREDENTIAL);
} elseif (Passwords::needsRehash($row[self::COLUMN_PASSWORD_HASH])) {
$row->update(array(
self::COLUMN_PASSWORD_HASH => Passwords::hash($password),
));
}
$arr = $row->toArray();
unset($arr[self::COLUMN_PASSWORD_HASH]);
return new Nette\Security\Identity($row[self::COLUMN_ID], $row[self::COLUMN_ROLE], $arr);
}
/**
* Adds new user.
* @param string
* @param string
* @return void
*/
public function add($username, $password, $role)
{
try {
$this->database->table(self::TABLE_NAME)->insert(array(
self::COLUMN_NAME => $username,
self::COLUMN_PASSWORD_HASH => Passwords::hash($password),
self::COLUMN_ROLE => $role,
));
} catch (Nette\Database\UniqueConstraintViolationException $e) {
throw new DuplicateNameException;
}
}
}
class DuplicateNameException extends \Exception
{}
?>
- Gl4dr
- Člen | 7
@premek_k Zavedený tam ten UserManager je
<?php
<?php
namespace App\Presenters;
use Nette;
use App\Forms\SignFormFactory;
use Nette\Database\Context;
use App\model\UserManager;
class SignPresenter extends BasePresenter
{
/* protected function beforeRender()
{
parent::beforeRender();
$this->setLayout('layoutLogin');
} */
private $database;
public $UserManager;
public function renderDefault()
{
}
protected function createComponentSignInForm()
{
$form = new Nette\Application\UI\Form;
$form->addText('username')
->setRequired('Prosím vyplňte své uživatelské jméno.')->setAttribute("placeholder","Uživ. jméno");
$form->addPassword('password')
->setRequired('Prosím vyplňte své heslo.')->setAttribute("placeholder","Heslo");;
$form->addSubmit('send', 'Přihlásit');
$form->onSuccess[] = array($this, 'signInFormSucceeded');
return $form;
}
public function signInFormSucceeded($form)
{
$values = $form->values;
try {
$this->user->login($values->username, $values->password);
$this->redirect('Dashboard:');
} catch (Nette\Security\AuthenticationException $e) {
$form->addError('Nesprávné přihlašovací jméno nebo heslo.');
$form->addError(hash('md5',$values->password));
}
}
public function actionOut()
{
$this->getUser()->logout();
$this->flashMessage('Odhlášení bylo úspěšné.');
$this->redirect('Sign:in');
}
protected function createComponentRegisterForm()
{
$roles = array(
'comp1' => 'Company 1',
'comp2' => 'Company 2',
'comp3' => 'Company 3',
);
$form = new Nette\Application\UI\Form;
$form->addText('username', 'Username:')
->setRequired('Please enter your username.');
$form->addPassword('password1', 'Password:')
->setRequired('Please enter your password.');
$form->addPassword('password2', 'Password again:')
->setRequired('Please enter your password.');
$form->addRadioList('radio2', 'Select your company:', $roles);
$form->addSubmit('send', 'Register');
//call method registerFormSucceeded() on success
$form->onSuccess[] = $this->registerFormSucceeded;
return $form;
}
public function registerFormSucceeded($form)
{
$values = $form->getValues();
$this->UserManager->add($values->username, $values->password, $values->radio2);
$this->flashMessage('You have been registered succesfuly.');
}
}
?>