Authenticator podla návodu

Upozornění: Tohle vlákno je hodně staré a informace nemusí být platné pro současné Nette.
Anubis
Člen | 6
+
0
-

Zdravím, snažil som sa spraviť authenticator podľa návodu na https://doc.nette.org/…thentication

Odpoveď nette:
Class App\Model\MyAuthenticator used in service ‚22_App_Model_MyAuthenticator‘ has not been found or is not instantiable.

Súbor MyAuthenticaror.php som uložil do app/model/ Bolo mi povedané, že robotloader si ho nájde..

V config.neon mám momentálne:

services
App\Model\UserManager
App\Model\MyAuthenticator
App\RouterFactory

router: @App\RouterFactory::createRouter
authenticator: MyAuthenticator

Už som tam vyskúšal napísať čokoľvek ale stále nič a už nad tým sedím 6 hodín..

Vopred vám ďakujem za rady ;)

Zax
Člen | 370
+
0
-

RobotLoader si to najde pouze tam, kde mu dovolíš prohledávat.

$configurator->createRobotLoader()
    ->addDirectory(...)
    ->addDirectory(...)
    ...
    ->register();
Šaman
Člen | 2666
+
0
-
  1. Hoď to na GitHub/BitBucket, ať se podíváme na zdrojáky. Tohle pravidlo platí všeobecně.
  2. Jestli vycházíš ze Sandboxu, tak si to tam RobotLoader najde. Tipuji na problém s namespace.
Anubis
Člen | 6
+
0
-

Ano, bolo to v namespacoch, a bol som sprdnutý aj za to že, som nepoužil spätné lomítka, čo v návode nebolo.. Už je to takto:

namespace App\Model;

use Nette\Security as NS;

class MyAuthenticator extends \Nette\Object implements NS\IAuthenticator
{
    public $database;
    protected  $user;

    function __construct(\Nette\Database\Context $database)
    {
        $this->database = $database;
    }

    function authenticate(array $credentials)
    {
        list($username, $password) = $credentials;
        $row = $this->database->table('users')->where('uid', $username)->fetch();
        if(!row)
        {
            throw new NS\AuthenticationException('User not found.');
        }
        if($row->heslo !== $password)
        {
            throw new NS\AuthenticationException('Invalid password.');
        }
        return new NS\Identity($row->id, $row->rights);
    }
}

A hlási mi to chybu: Service ‚user‘: Multiple services of type Nette\Security\IAuthenticator found: 22_App_Model_UserManager, authenticator

Neviete čo s tým je?

Mariocz
Člen | 52
+
0
-

Jak vypadá config? podle chyby bych řekl že máš tři authenticatory a neví kterej si vybrat.

David Matějka
Moderator | 6445
+
0
-

v sandboxu je UserManager, ktery take implementuje authenticator. Pokud ho nepotrebujes, muzes ho smazat (z configu i ten soubor, ktery je tusim v app/models)

Anubis
Člen | 6
+
0
-

v config.neon je len toto

parameters:


php:
	date.timezone: Europe/Prague
	# zlib.output_compression: yes


nette:
	application:
		errorPresenter: Error
		mapping:
			*: App\*Module\Presenters\*Presenter

	session:
		expiration: 14 days


services:
	- App\Model\UserManager
	- App\RouterFactory
	router: @App\RouterFactory::createRouter
	authenticator:	\App\Model\MyAuthenticator
Anubis
Člen | 6
+
0
-

No to snáď nie! Fakt stačilo zmazať ten UserManager :D Som zvedavý či mi to teraz bude fungovať, ešte nemám napísanú funkciu na spracovanie, ale už mi to zobrazilo moju stránku, ďakujem vám :)

dianjan
Člen | 8
+
0
-

Zdravím, snažil jsem se pomocí tohoto vlákna řešit stejný problém, ale když jsem udělal změny podle doporučení,dostal jsem se k následující chybové hlášce:

Class \App\Model\MyAuthenticator used in service ‚authenticator‘ has not been found or is not instantiable.

Zoufalý lamer prosí o radu :)

besanek
Člen | 128
+
0
-

Zkus promazat temp/cache. Pokud nepomůže tak ukaž jak \App\Model\MyAuthenticator vypadá.

dianjan
Člen | 8
+
0
-

Bohužel nepomohlo, ale chybová hláška se změnila na:
Service ‚authenticator‘: No service of type App\Model\Nette\Database\Context found. Make sure the type hint in App\Model\MyAuthenticator::__construct() is written correctly and service of this type is registered.

<?php

namespace App\Model;
use Nette\Security as NS;

class MyAuthenticator  extends \Nette\Object implements NS\IAuthenticator
{
    public $database;

    function __construct(Nette\Database\Context $database)
    {
        $this->database = $database;
    }

    function authenticate(array $credentials)
    {
        list($username, $password) = $credentials;
        $row = $this->database->table('users')
            ->where('name', $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);
    }
}
?>
Michal Vyšinský
Člen | 608
+
0
-

před Nette\Database\Context dej \

nebo ještě lépe: přidej use Nette\Database\Context; a v konstruktoru nech jen Context $database

besanek
Člen | 128
+
0
-

Backslash před Nette.

function __construct(Nette\Database\Context $database) //špatně
function __construct(\Nette\Database\Context $database) //dobře
dianjan
Člen | 8
+
0
-

díky moc tohle už funguje, ale… teď nastal další problém (předpokládám že s voláním toho autentifikátoru)

Call to undefined method App\Presenters\SignPresenter::login()

Omlouvám se za stupidní dotazy, ale teprve se rozkoukávám… ;)

<?php

namespace App\Presenters;

use Nette,
	App\Model;


/**
 * Sign in/out presenters.
 */
class SignPresenter extends BasePresenter
{


	/**
	 * Sign-in form factory.
	 * @return Nette\Application\UI\Form
	 */



        protected function createComponentSignInForm()
	{

		$form = new Nette\Application\UI\Form;
                $form->addText('username', 'Uživatel:')
			->setRequired('Prosím, zadejte jméno.');

		$form->addPassword('password', 'Heslo:')
			->setRequired('Nezadali jste heslo');

                $form->addSubmit('send', 'Přihlásit');

		// call method signInFormSucceeded() on success
		$form->onSuccess[] = $this->signInFormSucceeded;
		return $form;
	}


	public function signInFormSucceeded($form)
{
    $values = $form->values;
    //$user = $this->getUser();


    try {
        $this->login($values->username, $values->password);
        $this->redirect('Homepage:');

    } catch (Nette\Security\AuthenticationException $e) {
        $form->addError('Nesprávné přihlašovací jméno nebo heslo.');
    }
}


	public function actionOut()
	{
		$this->getUser()->logout();
		$this->flashMessage('Byli jste odhlášeni');
		$this->redirect('in');
	}

}
?>

Editoval dianjan (23. 5. 2014 11:41)

Michal Vyšinský
Člen | 608
+
0
-

To, že se rozkoukáváš neznamená, že bys neměl zkusit najít chybu sám, tím se člověk učí. Poradím:
Metoda SignPresenter::login neexistuje, ale je dostupná v Nette\Security\User :)

besanek
Člen | 128
+
0
-

Podívej se jak voláš logout() a jak login()

dianjan
Člen | 8
+
0
-

opravdu děkuji za trpělivost ;)
chybu to už nehlásí, ale i když zadám správné jméno i heslo tak mi to napíše:
Nesprávné přihlašovací jméno nebo heslo.

Michal Vyšinský
Člen | 608
+
0
-

Jak jej máš uložené v databázi? Jako plain text, nebo md5 hash?

dianjan
Člen | 8
+
0
-

Zkoušel jsem obě možnosti a bohužel ani jedna nefunguje…

Michal Vyšinský
Člen | 608
+
0
-

No v databázi jej musíš mít jako md5, to je jasné. Jseš si jistý, že zadáváš správně jméno a heslo? Ještě mě napadá: jakou délku máš na heslo v databázi? md5 má 32 znaků, tak musíš mít aspoň takovou délku.

dianjan
Člen | 8
+
0
-

To byl ten problém… Ještě jednou děkuji za cenné rady a trpělivost…

leninzprahy
Člen | 150
+
0
-

Ještě bych doporučil na hashování používat něco jiného než md5, zkus třeba funkci crypt() kterou s algoritmem Blowfish doporučuje Michal Špaček

mirimCZ
Člen | 24
+
0
-

A když jsme u toho doporučování, já bych doporučil pro větší bezpečnost přidat k heslu salt (první výsledek).

Editoval mirimCZ (23. 5. 2014 13:30)

iguana007
Člen | 970
+
0
-

Nebo mrkni do sandboxu, jak se to dá udělat: https://github.com/…rManager.php

Mimochodem, metoda Passwords::hash, která se tam volá může mít i druhý parametr, právě ten salt, jak už tady zmínili ostatní. Když jej ale nepředáš, tak ti to Nette osolí samo, viz.: https://github.com/…asswords.php#L33

Editoval iguana007 (23. 5. 2014 14:18)