How to use custom authenticator to authenticate from database?
- kevin.waterson@gmail.com
- Member | 81
I am setting up Authentication from database using example from https://doc.nette.org/…thentication
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)
- Marek Bartoš
- Nette Blogger | 1273
namespace App\Model\SiteAuthenticator
+
class SiteAuthenticator
→
App\Model\SiteAuthenticator\SiteAuthenticator
- kevin.waterson@gmail.com
- Member | 81
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]);
}
}
?>
- Marek Bartoš
- Nette Blogger | 1273
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
- CZechBoY
- Member | 3608
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)
- kevin.waterson@gmail.com
- Member | 81
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]);
}
}
?>