How to use custom authenticator to authenticate from database?

9 months ago

+
0
-

I am setting up Authentication from database using example from https://doc.nette.org/…cess-control
The database connection works fine, but the custom authenticator is not found.
The file which contains the custom authenticator is located in app/Model/SiteAuthenticator.php

My config.neon file contains:

services:
        authenticator: App\Model\SiteAuthenticator
        router: App\Router\RouterFactory::createRouter

The app/Model/SiteAuthenticator.php looks like this:

<?php

namespace App\Model\SiteAuthenticator;

use Nette\Security\Passwords;
use Nette\Security\IAuthenticator;

class SiteAuthenticator implements IAuthenticator
{
        public function __construct(Nette\Database\Context $database, Nette\Security\Passwords $passwords)
        {
                $this->database = $database;
                $this->passwords = $passwords;
        }

        public function authenticate(array $credentials): Nette\Security\IIdentity
        {
                [$username, $password] = $credentials;

                $row = $this->database->table('users')
                        ->where('username', $username)->fetch();

                if (!$row) {
                        throw new Nette\Security\AuthenticationException('User not found.');
                }

                if (!$this->passwords->verify($password, $row->password)) {
                        throw new Nette\Security\AuthenticationException('Invalid password.');
                }

                return new Nette\Security\Identity($row->id, $row->role, ['username' => $row->username]);
        }
}

?>

The error I am getting is:

Nette\DI\ServiceCreationException
Service 'authenticator': Class App\Model\SiteAuthenticator not found.

Last edited by kevin.waterson@gmail.com (2019-11-26 20:44)

9 months ago

Mabar
Member | 286
+
0
-

namespace App\Model\SiteAuthenticator + class SiteAuthenticatorApp\Model\SiteAuthenticator\SiteAuthenticator

9 months ago

+
0
-

Thanks Mabar, a little closer, except I now get an error

Compile Error
Declaration of App\Model\SiteAuthenticator\SiteAuthenticator::authenticate(array $credentials): App\Model\SiteAuthenticator\Nette\Security\IIdentity must be compatible with Nette\Security\IAuthenticator::authenticate(array $credentials): Nette\Security\IIdentity

My SiteAuthenticator class looks like this:

<?php

namespace App\Model\SiteAuthenticator;

use Nette\Security\IIdentity;
use Nette\Security\Passwords;
use Nette\Security\IAuthenticator;

class SiteAuthenticator implements IAuthenticator
{
        public function __construct(Nette\Database\Context $database, Nette\Security\Passwords $passwords)
        {
                $this->database = $database;
                $this->passwords = $passwords;
        }

        public function authenticate(array $credentials): Nette\Security\IIdentity
        {
                [$username, $password] = $credentials;

                $row = $this->database->table('users')
                        ->where('username', $username)->fetch();

                if (!$row) {
                        throw new Nette\Security\AuthenticationException('User not found.');
                }

                if (!$this->passwords->verify($password, $row->password)) {
                        throw new Nette\Security\AuthenticationException('Invalid password.');
                }

                return new Nette\Security\Identity($row->id, $row->role, ['username' => $row->username]);
        }
}
?>

9 months ago

Mabar
Member | 286
+
+1
-

public function authenticate(array $credentials): Nette\Security\IIdentity – you are using relative namespace to your actual namespace, it's a App\Model\SiteAuthenticator + Nette\Security\IIdentity.

You should either use use use Nette\Security\IIdentity; with IIdentity or just absolute namespace \Nette\Security\IIdentity

9 months ago

CZechBoY
Member | 3588
+
0
-

There is alredy use for that – just write

 public function authenticate(array $credentials): IIdentity

as i check whole code im thinking about importing only Nette namespace, you use full ns path everywhere…
use Nette

btw check some tutorial for php oop as this is not much related to framework itself

Last edited by CZechBoY (2019-11-26 23:55)

9 months ago

+
0
-

Thanks Mabar, the working code for the Authenticator class is:

<?php

namespace App\Model\SiteAuthenticator;

use \Nette\Security\IIdentity;
use \Nette\Security\Passwords;
use \Nette\Security\IAuthenticator;

class SiteAuthenticator implements IAuthenticator
{
        public function __construct(\Nette\Database\Context $database, \Nette\Security\Passwords $passwords)
        {
                $this->database = $database;
                $this->passwords = $passwords;
        }

        public function authenticate(array $credentials): \Nette\Security\IIdentity
        {
                [$username, $password] = $credentials;

                $row = $this->database->table('users')
                        ->where('username', $username)->fetch();

                if (!$row) {
                        throw new Nette\Security\AuthenticationException('User not found.');
                }

                if (!$this->passwords->verify($password, $row->password)) {
                        throw new Nette\Security\AuthenticationException('Invalid password.');
                }

                return new Nette\Security\Identity($row->id, $row->role, ['username' => $row->username]);
        }
}
?>