Přihlášení z db, undefined offset: 1

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

Potřeboval bych prosím poradit na přihlášení z db a už nevím, kde je co špatně.

Vypisuje mi to chybu: „Undefined offset: 1“ ( list($username, $password) = $credentials;)

Pokud to dobře chápu, tak se mi netahá jedná z proměnných?

SingPresenter

<?php

namespace App\Presenters;

use Nette;
use Nette\Application\UI\Form;
use App\Model\UserManager;
use Nette\Security\User;



class SignPresenter extends Nette\Application\UI\Presenter
{
    private $userManager;

    public function __construct (UserManager $userManager)
{
    $this->userManager = $userManager;
}


    protected function createComponentSignInForm()
    {
        $form = new Form;
        $form->addText('username', 'Uživatelské jméno:')
            ->setRequired('Prosím vyplňte své uživatelské jméno.');

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


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

        $form->onSuccess[] = [$this, 'signInFormSucceeded'];
        return $form;
    }
    /**
 * @param $form Nette\Application\UI\Form
 * @param $values Nette\Utils\ArrayHash
 */
public function signInFormSucceeded($form, $values)
{
    try {
        $pole[] = array($values->username, $values->password);
        $this->userManager->authenticate($pole);
        $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('Odhlášení bylo úspěšné.');
    $this->redirect('Homepage:');
}
public function actionCreate()
{
    if (!$this->getUser()->isLoggedIn()) {
        $this->redirect('Sign:in');
    }

}



}

UserManager

<?php

namespace App\Model;

use Nette;
use Nette\Security\Passwords;
use \App\Model;


/**
 * Users management.
 */
class UserManager extends \Nette\Object implements Nette\Security\IAuthenticator
{
	use Nette\SmartObject;

	const
		TABLE_NAME = 'users',
		COLUMN_ID = 'id',
		COLUMN_NAME = 'username',
		COLUMN_PASSWORD_HASH = 'password',
		COLUMN_EMAIL = 'email',
		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
	 * @param  string
	 * @return void
	 * @throws DuplicateNameException
	 */
	public function add($username, $email, $password)
	{
		try {
			$this->database->table(self::TABLE_NAME)->insert([
				self::COLUMN_NAME => $username,
				self::COLUMN_PASSWORD_HASH => Passwords::hash($password),
				self::COLUMN_EMAIL => $email,
			]);
		} catch (Nette\Database\UniqueConstraintViolationException $e) {
			throw new DuplicateNameException;
		}
	}

}



class DuplicateNameException extends \Exception
{}

Díky za radu

David Matějka
Moderator | 6445
+
+1
-

ahoj,
konstrukcí

$pole[] = array($values->username, $values->password);

vytvoris dvourozmerne pole, ktere vypada jako array(array(username, password))

spravne by to melo byt

$pole = array($values->username, $values->password);

tzn bez tech zavorek.

ale ty vubec tady nechces volat metodu authenticate na user manager, ale metodu login na Nette\Security\User, mrkni se do sandboxu https://github.com/nette/sandbox

CZechBoY
Člen | 3608
+
0
-

Dáváš to do prvni položky pole místo jako celé.

$pole[] = ....

Přepiš na

$pole = array($values->..., $values->...);
mysak9
Člen | 18
+
0
-

Děkuji za rady, pole jsem si upravil.

Ale přihlášení stále někde selhává, pokud to volám na

$this->user->login($values->username, $values->password);

Tak mi připadá, že se to s db vůbec nespojí, jelikož to pouze vyhodí špatné heslo,login.

CZechBoY
Člen | 3608
+
0
-

Selhává znamená co? Špatné heslo? Máš dostatečně velký sloupec na hash?

mysak9
Člen | 18
+
0
-

Ano, stále to vyhazuje hlášku „Nesprávné přihlašovací jméno nebo heslo.“, ať zkusím jakýkoliv acc co mám v db. Co se týče db, tak mám sloupec dostatečně velký, to už jsem kontroloval, než jsem vkládal dotaz.

mysak9
Člen | 18
+
0
-

Tak už jsem se kousek pohnul, přepsal jsem si:

try {
		$user = $this->getUser();
		$values = $form->getValues();
		$user->login($values->username, $values->password);
		$this->flashMessage('Přihlášení bylo úspěšné.', 'success');
		$this->redirect('Homepage:');
	} catch (NS\AuthenticationException $e) {
		$form->addError('Neplatné uživatelské jméno nebo heslo.');
	}

A nyní mi to vyhazuje chybu:
"Nette\Security\AuthenticationException #2

The password is incorrect."

Ale v db mám heslo v pořádku, mělo by mít 60 znaků což mám.

Hlásí mi to, že je něco špatně tady:

} elseif (!Passwords::verify($password, $row[self::COLUMN_PASSWORD_HASH])) {
                throw new Nette\Security\AuthenticationException('The password is incorrect.', self::INVALID_CREDENTIAL);

Editoval mysak9 (5. 2. 2017 19:31)

Mysteria
Člen | 797
+
0
-

A ty uživatele jsi si do databáze přidával jak? Pokud manuálně, tak ty hesla tam musíš vzít z Passwords::hash('tvojeHeslo').

mysak9
Člen | 18
+
0
-

Registrace mi funguje, přidávám regpresenter, kde mám hash na heslo

<?php

namespace App\Presenters;

use Nette;
use Nette\Application\UI\Form;
use Nette\Security\Passwords;




class RegPresenter extends Nette\Application\UI\Presenter
{

    /**@var Nette\Database\context */
    private $database;

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

    }


    protected function createComponentRegistrationForm()
    {
        $form = new Form;
        $form->addEmail('email', 'E-mail')
              ->setRequired('Prosím vyplňte e-mail')
              ->addRule(function ($control) {
              return !$this->database->query('SELECT email FROM users WHERE email = ? LIMIT 1', $control->value)->fetch();
              }, 'Uživatel existuje');


        $form->addText('username', 'Uživatelské jméno:')
            ->setRequired('Prosím vyplňte své uživatelské jméno.')
            ->addRule(function ($control) {
              return !$this->database->query('SELECT username FROM users WHERE username = ? LIMIT 1', $control->value)->fetch();
              }, 'Uživatel existuje');

        $form->addPassword('password', 'Heslo:')
             ->setRequired('Prosím vyplňte své heslo.')
             ->addRule(Form::MIN_LENGTH, 'Minimální délka hesla je %d znaků', 1);


        $form->onSuccess[] = [$this, 'registrationFormSucceeded'];
        $form->addSubmit('send', 'Přihlásit');


        return $form;
    }



    Public function registrationFormSucceeded($form, $values)
    {

        $values["password"] = Passwords::hash('password');
        $values["role"] = 'registred';

        $this->database->table('users')->insert($values);

        $this->flashMessage('Byl jste zaregistrován', 'success');
    $this->redirect('Homepage:');}

    }
jiri.pudil
Nette Blogger | 1029
+
+2
-
$values["password"] = Passwords::hash('password');

Na tomhle řádku vidím problém :)

mysak9
Člen | 18
+
0
-

@jiri.pudil Tento řádek, jsem tam přidával schválně, jelikož pokud ho tam nemám, tak mi hashování nefunguje a do db se uloží heslo tak jak ho vložím z formuláře.

abc
Člen | 92
+
+6
-

@mysak9 nj, ale ten řádek má být takto (teda pokud nechceš mít heslo ‚password‘)

$values["password"] = Passwords::hash($values['password']);
mysak9
Člen | 18
+
0
-

@abc Díky, moje blbos :/… Tohle jsem si neuvědomil, že tam nepředávám $values. Díky moc za radu :)