Nette – authenticator …
- Takeshi
- Člen | 596
Caute … viete ako pouzit authenticator, aby mi tahalo udaje z databazy
… zatial pouzivam toto … na zaciatok
<?php
$authenticator = new Nette\Security\SimpleAuthenticator(array(
'john' => 'pass1',
'kathy' => '12345', // Kathy, this is a very weak password!
'takeshi' => 'kitano'
));
$user->setAuthenticator($authenticator);
?>
je tam spomenuty (na nette strankach) aj MyAuthenticator, ale neviem ako ho mam pouzit
Diki
- Vojtěch Dobeš
- Gold Partner | 1316
Autentikátorem může být libovolný objekt implementující rozhraní
Nette\Security\IAuthenticator
. Musí implementovat 1 metodu
authenticate()
, která buď vrací Identity
(při
úspěšném přihlášení) nebo NULL
. Nejsnáze se nastavuje
v configu (doufám že nekecám a toto funguje):
services:
authenticator:
class: MyAuthenticator
Možná by Takeshi bylo fajn nebojovat s minimálním limitem subjektu vláken a snažit se vyplodit popisnější název problému. Mohlo by to do budoucna pomoci i ostatním.
- Takeshi
- Člen | 596
vojtech.dobes napsal(a):
Co sa tyka konfiguracie, mam to nastavene takto, a nefunguje
services:
database: @Nette\Database\Connection
authenticator: MyAuthenticator( @database::table(users) )
takze ak mas prosim inu radu, sem s nou :-) … a co sa tyka toho mojho skrateneho textu … ja osm mal pocit ze som ho nacrtol jasne … no mozno nie (ale to som potom nemal v plane)
- Takeshi
- Člen | 596
OK tak ten moj problem upresnim: Potrebujem aby mi udaje (username, password, role [user,admin]) nacitavalo z databazy … pre istotu ukazem moj Presenter a pod nim aj configuracny subor config.neon ..
<?php
class LoginPresenter extends BasePresenter
{
public function renderDefault()
{
$user = $this->getUser();
if($user->isLoggedIn()){
$this->redirect('Homepage:default');
}
$authenticator = new Nette\Security\SimpleAuthenticator(array(
'john' => 'pass1',
'kathy' => '12345', // Kathy, this is a very weak password!
'takeshi' => 'kitano'
));
$user->setAuthenticator($authenticator);
if ($this['login']->isSuccess()){
$username = $_POST['username'];
$password = $_POST['password'];
/*Pokusa sa prihlasit*/
try {
// pokusíme se přihlásit uživatele...
$user->login($username, $password);
$this->redirect('Homepage:default');
// ...a v případě úspěchu presměrujeme na další stránku
//$this->redirect('Homepage:default');
} catch (Nette\Security\AuthenticationException $e) {
$e->getMessage();
}
}
}
public function createComponentLogin(){
$form = new Nette\Application\UI\Form;
$form->setAction('');
$form->setMethod('POST');
$form->addText('username',null,16);
$form->addPassword('password',null,16);
$form->addSubmit('login','Login');
return $form;
}
}
?>
#
# SECURITY WARNING: it is CRITICAL that this file & directory are NOT accessible directly via a web browser!
#
# If you don't protect this directory from direct web access, anybody will be able to see your passwords.
# https://nette.org/en/security-warning
#
common:
parameters:
database:
driver: mysql
host: localhost
dbname: database
user: root
password:
php:
date.timezone: Europe/Prague
# session.save_path: "%tempDir%/sessions"
# zlib.output_compression: yes
nette:
session:
expiration: '+ 14 days'
database:
default:
dsn: '%database.driver%:host=%database.host%;dbname=%database.dbname%'
user: %database.user%
password: %database.password%
services:
database: @Nette\Database\Connection
authenticator: MyAuthenticator( @database::table(users) )
factories:
production < common:
development < common:
.. a s tymto nastavenim mi to nefunguje, viete preco? (MyAuthenticator.php (ktorý je aj v Nette dokumentacií) mám uložený v priečinku models)
Editoval Takeshi (22. 4. 2012 14:23)
- Takeshi
- Člen | 596
A ked ten MyAuthenticator zaregistrujem …$user->setAuthenticator(new MyAuthenticator); ukazuje mi nasledovnu chybu
Argument 1 passed to MyAuthenticator::__construct() must be an instance of Nette\Database\Connection, none given, called in C:\Program Files (x86)\EasyPHP-5.3.8.0\www\PUSKAS\app\presenters\LoginPresenter.php on line 20 and defined
- Takeshi
- Člen | 596
ricco24 napsal(a):
1. Pouzitim registracie: $user->setAuthenticator($this->context->authenticator); mi hlasi nasledovnu chybu
Argument 1 passed to MyAuthenticator::__construct() must be an instance of Nette\Database\Connection, instance of Nette\Database\Table\Selection given, called in C:\Program Files (x86)\EasyPHP-5.3.8.0\www\PUSKAS\temp\cache\_Nette.Configurator\_-285bac8f7b7d3ea72485a759a142673d.php on line 108 and defined search►
a pre ISTOTU este raz ukazem moj Presenter … (trosicka zmeneny)
<?php
class LoginPresenter extends BasePresenter
{
public function renderDefault()
{
$user = $this->getUser();
if($user->isLoggedIn()){
$this->redirect('Homepage:default');
}
$user->setAuthenticator($this->context->authenticator);
if ($this['login']->isSuccess()){
$username = $_POST['username'];
$password = $_POST['password'];
/*Pokusa sa prihlasit*/
try {
// pokusíme se přihlásit uživatele...
$user->login($username, $password);
$this->redirect('Homepage:default');
// ...a v případě úspěchu presměrujeme na další stránku
//$this->redirect('Homepage:default');
} catch (Nette\Security\AuthenticationException $e) {
$e->getMessage();
}
}
}
public function createComponentLogin(){
$form = new Nette\Application\UI\Form;
$form->setAction('');
$form->setMethod('POST');
$form->addText('username',null,16);
$form->addPassword('password',null,16);
$form->addSubmit('login','Login');
return $form;
}
}
?>
2. MyAuthenticator.php mam vytvorenu:
Nazov_Projektu
|
|-app
|-models
|-MyAuthenticator.php
3. Konfiguracny dubor je nacrtnuty vyssie
- ricco24
- Člen | 141
Pozrel som si ako je napísaný MyAuthenticator v dokumentácii.
v config.neon by si mal teda mať toto
services:
database: @Nette\Database\Connection
authenticator: MyAuthenticator( @database )
Je pravda že v prípade ak máš v configu len jeden Authenticator tak riadok
$user->setAuthenticator($this->context->authenticator);
môžeš úplne vypustit.
Editoval ricco24 (22. 4. 2012 18:43)
- Takeshi
- Člen | 596
ricco24 napsal(a):
Tak tu je ta trieda … a zmenil som Nette\Database\Connection na Nette\Database\Table\Selection ako si mi poradil .. no stale chyba
<?php
use Nette\Security as NS;
class MyAuthenticator extends Nette\Object implements NS\IAuthenticator
{
public $connection;
function __construct(Nette\Database\Table\Selection $connection)
{
$this->connection = $connection;
}
function authenticate(array $credentials)
{
list($username, $password) = $credentials;
$row = $this->connection->table('users')
->where('username', $username)->fetch();
if (!$row) {
throw new NS\AuthenticationException('User not found.');
}
if ($row->password !== md5($password)) {
throw new NS\AuthenticationException('Invalid password.');
}
return new NS\Identity($row->id, $row->role);
}
}
?>
A co sa tyka config.neon, tak tam som to takisto zmenil tak ako mi to poradil ricco24
.. stale ma problem v triede MyAuthenticator vo funkcii __construct()
- Takeshi
- Člen | 596
ricco24 napsal(a):
Pokial zmenim iba tu konfiguraciu teda
services:
database: @Nette\Database\Connection
authenticator: MyAuthenticator( @database )
a do presentera som vlozil tak ako si mi poradil …
<?php
$user->setAuthenticator($this->context->authenticator);
?>
… tak je vsetko ok
Editoval Takeshi (22. 4. 2012 20:34)
- Takeshi
- Člen | 596
davidm napsal(a):
… zmen to zpatky na Connection a ten cfg nech jak je
Tak v MyAutenticate som ponechal …
Nette\Database\Connection
a configuraciu som teda nechal na ..
services:
database: @Nette\Database\Connection
authenticator: MyAuthenticator( @database )
chybu mi nehadze, ale udaje mi z databazi nacitavat nechce
a aby som bol co najpresnejsi v databaze mam tabulku:
users (id,username,password,role)
a s registraciou/bez .. je to rovnake
$user->setAuthenticator($this->context->authenticator);
- JuniorJR
- Člen | 181
davidm napsal(a):
ona by spis mela bejt v nakym callbacku navazanym na onSuccess
Souhlasím a nechápu, proč dotyčný píše:
$username = $_POST['username'];
$password = $_POST['password'];
Doporučuju ti vypsat hodnoty, které se pošlou z formuláře a ověřit, zda se opravdu shodují s hodnotami v db.
Editoval JuniorJR (22. 4. 2012 21:50)
- Takeshi
- Člen | 596
JuniorJR napsal(a):
Souhlasím a nechápu, proč dotyčný píše:
$username = $_POST['username']; $password = $_POST['password'];
No tak vyssie je cely LoginPresenter.php, takze tie hodnoty sa najprv nacitaju do premenych a potom sa s nimi pokusam prihlasit, neviem co je na tom take nepochopitelne :-)
A pokial som pouzival (uz spomenute)
<?php
$authenticator = new Nette\Security\SimpleAuthenticator(array(
'john' => 'pass1',
'kathy' => '12345', // Kathy, this is a very weak password!
'takeshi' => 'kitano'
));
$user->setAuthenticator($authenticator);
?>
tak nebol ziaden problem … A ako by si mi ty doporucil tie hodnoty porovnat, ked ich neviem dostat z databazy?? … teda pokial nemyslis klasicke pouzitie Nette\database a pomocou $database->table(‚users‘) si tie vypisy porovnat … Ja by som to skor chcel iresit pomocou MyAuthenticator
Editoval Takeshi (22. 4. 2012 21:59)
- ricco24
- Člen | 141
Zdá sa mi že v tom je už príliž velký zmätok. Toto riešenie by ti malo fungovať. Inak radím ti pozrieť si aj SignPresenter zo sandboxu. Je to skoro to isté.
class LoginPresenter extends BasePresenter
{
public function renderDefault()
{
$user = $this->getUser();
if($user->isLoggedIn()){
$this->redirect('Homepage:default');
}
}
public function createComponentLoginForm(){
$form = new Nette\Application\UI\Form;
$form->addText('username',null,16);
$form->addPassword('password',null,16);
$form->addSubmit('login','Login');
$form->onSuccess[] = callback($this, 'loginFormSubmitted')
return $form;
}
public function loginFormSubmitted($form) {
$values = $form->getValues();
try {
$user->login($values->username, $values->password);
$this->redirect('Homepage:default');
} catch (Nette\Security\AuthenticationException $e) {
$e->getMessage();
}
}
}
Authenticator použijeme pre jednoduchosť ten ktorý je uvedený v dokumentácii a ktorý už máš implementovaný
use Nette\Security as NS;
class MyAuthenticator extends Nette\Object implements NS\IAuthenticator
{
public $connection;
function __construct(Nette\Database\Connection $connection)
{
$this->connection = $connection;
}
function authenticate(array $credentials)
{
list($username, $password) = $credentials;
$row = $this->connection->table('users')
->where('username', $username)->fetch();
if (!$row) {
throw new NS\AuthenticationException('User not found.');
}
if ($row->password !== md5($password)) {
throw new NS\AuthenticationException('Invalid password.');
}
return new NS\Identity($row->id, $row->role);
}
}
a v config.neon
services:
database: @Nette\Database\Connection
authenticator: MyAuthenticator( @database )
Dúfam že som na nič nezabudol.
Editoval ricco24 (22. 4. 2012 22:19)
- 22
- Člen | 1478
@ricco24: toto je co
if ($form->isSuccess())
? nejsi náhodou v callbacku
onSuccess[], tedy v callbacku, který se vykoná je v případě úspěšného
odeslání?
@takeshi: v distribuci máš tvůj problém
vyřešený, jmenuje se to sandbox
, tam si prohlídni, ja se to
správně řeší.
SimpleAuthenticator v neonu:
nette:
security:
users:
admin: admin123
Editoval 22 (22. 4. 2012 22:17)
- Takeshi
- Člen | 596
No tak ja som v koncoch … chybu mi neukazuje, prihlasit sa mi aj tak neda (zmenil som config, loginPresenter, MyAuthenticator) … tak ako to urobil ricco24 a nic.
Co sa tyka SimpleAuthenticator … pomocou neho mi to islo, len som pri tom nepouyival databazu
Ak by pomohlo poslal by som aj cely moj mini-prijekt … na ktorom si skusam iba nove veci
- Takeshi
- Člen | 596
Tak po malom bádaní som zistil, že ono to pracuje s databazou dobre, teda mi najde aj danych uzivatelov, ale HESLÁ, čo sú k nim pridelené jednoducho neakceptuje …
napr.: používateľ = takeshi a heslo, nemu pridelene = kitano
teda registruje uzivatela takeshi ale neberie mi jeho heslo
- Ot@s
- Backer | 476
Takeshi napsal(a):
Tak po malom bádaní som zistil, že ono to pracuje s databazou dobre, teda mi najde aj danych uzivatelov, ale HESLÁ, čo sú k nim pridelené jednoducho neakceptuje …
napr.: používateľ = takeshi a heslo, nemu pridelene = kitano
teda registruje uzivatela takeshi ale neberie mi jeho heslo
A není problém v tom, že máš heslo v DB jako plaintext a
porovnávání se provádí oproti md5
? Dumpni si výpis záznamu
z DB a hned to uvidíš.
Sandbox (včetne examples) je v každé „instalačce“ Nette. Jinak viz Nette sandbox na Githubu (rovnou download).
Editoval Ot@s (22. 4. 2012 23:02)
- 22
- Člen | 1478
Myslím, že Ot@s bude mít pravdu, vydumpuj si pomocí dump(), jake heslo se posílá na ověření a jaké heslo je v DB, pokud se neshodují, tak samozřejmě to přes Authenticator nemůže projít.
P.S.: Sandbox je přímo v dustribuci Nette, jeden z adresářu, kde je předpřipavená kostra aplikace a je tam i SignPresenter s přihlašovacím formulářem včetně modelu a Authenticatoru.
Editoval 22 (22. 4. 2012 23:06)
- Takeshi
- Člen | 596
No tak s tym sandboxom si to pozriem …
→ urobil som si dump() aj vypisu z formulara aj s databazy … zhoduju sa … takze neviem preco mi uzivatela berie a jeho heslo nie …
no ak nemate nejaky napad … tak len skusit stastie s tym sandboxom (vedel som o nom, len som na neho uplne zabudol … ) … ako to ja vidim,,, je tu len jedna mala blba chyba, ktora mi zneprijemnuje zivot :-) :-D .....
- Takeshi
- Člen | 596
UZ som nasiel chybu, ⇒ uz sa mi da prihlasit (pouzil som Authenticator nie MyAuth…)
CHYBA BOLA V tomto
<?php
if ($row->password !== $this->calculateHash($password)) {...}
?>
, ktory ked som zmenil na
<?php
if ($row->password !== $password) {...}
?>
tak to islo … problem pravdepodobne ale teraz nastal, ze to nebude tak bezpecne
co na to hovorite??
- Takeshi
- Člen | 596
Myiyk napsal(a):
O dost bezpečnější je ukládat heslo jako hash.
Ale jestli to spouštíš jen sám sobě na localhostu, tak je to jedno.
Ja viem, ze to je menej bezpecne, ked zamenim toto
<?php
if ($row->password !== $this->calculateHash($password)) {...}
?>
za toto …
<?php
if ($row->password !== $password) {...}
?>
… ale ked pouzijem hash, tak mam problem z heslom, teda nezhoduje sa … len v tom druhom pripade, bez calculateHash
A aby sa nepovedalo, skusal som aj prihlasovanie z prikladu, zo sandboxu, jednoducho som si skopiroval subory signPresenter a jeho sablonu, ale bez vysledne (fungovalo to iba ak som pouzil SQLITE databazu ‚demo.db‘)
Editoval Takeshi (23. 4. 2012 22:47)
- Takeshi
- Člen | 596
duke napsal(a):
Takeshi napsal(a):
… ale ked pouzijem hash, tak mam problem z heslom, teda nezhoduje sa … len v tom druhom pripade, bez calculateHashAby ti to fungovalo, musíš si do db to heslo ukládat zahashované. A pokud ti jde o bezpečnost, tak bys měl také solit. :-)
No vidis, to som nevedel … clovek sa uci kazdym dnom :-)