You cannot serialize or unserialize PDO instances

5 months ago

MakotOnoda
Member | 3
+
0
-

Good Morning,

I've been trying to get a login for some time now.
First one dan wanted the other one not now I unfortunately get a “You cannot serialize or unserialize PDO instances” error.

In this regard, I've already looked at the old post https://forum.nette.org/…do-instances me, but unfortunately without success, unfortunately, the post is already 3 years old.

Now I hope you can help me here.

Application info:

<?php

namespace App\Presenters;

use Nette;
use Nette\Application\UI\Form;
use Nette\Database\Connection;
use App\Forms\SignFormFactory;
use Nette\Security\Passwords;
//use Nette\Security\User;

class SignPresenter extends Nette\Application\UI\Presenter
{

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

    /** @var User */
    public $user;

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

    protected function createComponentSignInForm()
    {
        $form = new Form;
        $form->addText('username', 'Username:')
            ->setRequired('Please enter your username.');

        $form->addPassword('password', 'Password:')
            ->setRequired('Please enter your password.');

        $form->addSubmit('send', 'Login');

        $form->onSuccess[] = [$this, 'signInFormSucceeded'];
        return $form;
    }

    public function signInFormSucceeded(Form $form, Nette\Utils\ArrayHash $values)
    {
        $userDB = $this->database->table('d-user')->where('Nick', $values->username)->fetch();
        $passwordDB = Passwords::verify($values->password, $userDB['Passwort']);

        $firmaStatus = $this->database->table('d-firma')->where('ID', $userDB['D-Firma_ID'])->fetch();
        if(!$userDB != !$passwordDB){
            $this->flashMessage('Benutzer und/oder Passwort falsch.');
        }elseif(!$firmaStatus['Active']){
            $this->flashMessage('Ihr Unternehmen ist nicht berechtigt diese Anwendung zu nutzen.');
        }elseif(!$userDB['Active']){
            $this->flashMessage('Benutzer wurde deaktiviert, bitte wenden sie sich an ihren Vorgesetzten.');
        }else{
            $user = $this->getUser();
            $user->login($userDB->Nick, $values->password);
            $user->setExpiration('90 days');
            //$this->redirect('MainHomepage:');
        }
    }

}
<?php

namespace App\Model;

use Nette;
use Nette\Security\Passwords;


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

    const
        TABLE_NAME = 'd-user',
        COLUMN_ID = 'id',
        COLUMN_NAME = 'Nick',
        COLUMN_PASSWORD_HASH = 'Passwort',
        COLUMN_EMAIL = 'Mail',
        COLUMN_ROLE = 'Grade';


    /** @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([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['Grade'], $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
{
}

This is my motto I fall back on:

CREATE TABLE `d-user` (
  `ID` int(11) NOT NULL,
  `R-V.name` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
  `R-V2.name` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
  `R-N.name` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
  `Grade` enum('Chef','Schicht-Leiter','Normal','Admin') COLLATE utf8_unicode_ci DEFAULT 'Normal',
  `Nick` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
  `Passwort` varchar(150) COLLATE utf8_unicode_ci DEFAULT NULL,
  `Active` tinyint(1) DEFAULT '1',
  `Status` enum('Intern','Extern') COLLATE utf8_unicode_ci DEFAULT NULL,
  `Mail` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
  `D-Firma_ID` int(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

Now I always get the above error …

This is currently happening via XAMPP Local

Error

...\htdocs\DataClown\app\presenters\SignPresenter.php:55 source  Nette\Security\User->login(arguments)
45:
46:            $firmaStatus = $this->database->table('d-firma')->where('ID', $userDB['D-Firma_ID'])->fetch();
47:            if(!$userDB != !$passwordDB){
48:                $this->flashMessage('Benutzer und/oder Passwort falsch.');
49:            }elseif(!$firmaStatus['Active']){
50:                $this->flashMessage('Ihr Unternehmen ist nicht berechtigt diese Anwendung zu nutzen.');
51:            }elseif(!$userDB['Active']){
52:                $this->flashMessage('Benutzer wurde deaktiviert, bitte wenden sie sich an ihren Vorgesetzten.');
53:            }else{
54:                $user = $this->getUser();
55:                $user->login($userDB->Nick, $values->password); <----- ERROR
56:                $user->setExpiration('90 days');
57:                //$this->redirect('MainHomepage:');
58:            }
59:        }

Last edited by MakotOnoda (2018-07-20 10:15)

5 months ago

Ondřej Kubíček
Member | 353
+
0
-

at first glance it looks good
the best way is to debug and look what happen inside of login function

5 months ago

Ondřej Kubíček
Member | 353
+
+2
-

btw why do you twice check the correctness of your password? in signInFormSucceeded then in authenticate function

5 months ago

MakotOnoda
Member | 3
+
0
-

The signInForm Succeeded function was finished at first, after that I first came up to the class ‘UserManager’

Even if I shorten the code still PDO.

public function signInFormSucceeded(Form $form, Nette\Utils\ArrayHash $values)
    {
        $user = $this->getUser();

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

Last edited by MakotOnoda (2018-07-20 12:39)

5 months ago

MakotOnoda
Member | 3
+
0
-

Sorry I was just stupid and blind -.-

I found the mistake, he was in UserManager

class UserManager implements Nette\Security\IAuthenticator
{
    use Nette\SmartObject;

    const
        TABLE_NAME = 'd-user',
        COLUMN_ID = 'ID', <----- before 'id'
        COLUMN_NAME = 'Nick',
        COLUMN_PASSWORD_HASH = 'Passwort',
        COLUMN_EMAIL = 'Mail',
        COLUMN_ROLE = 'Grade';

...

The Colum_ID was previously written in lower case than “id” but I have an “ID” in the database ..

Last edited by MakotOnoda (2018-07-20 13:18)