Jednoduchý autentifikátor
- KrKOo
- Člen | 3
Ahojte, chcel by som spraviť nejaký jednoduchý autentifikátor na moju
stránku ale neviem sa pohnúť kvôli jednej chybe.
Píše mi to: Service ‚24_App_Model_UserManager‘ (type of
App\Model\UserManager): Service of type Nette\Security\Passwords needed by
$passwords in App\Model\UserManager::__construct() not found. Did you register
it in configuration file?
Ďakujem za akúkoľvek pomoc alebo radu.
UserManager.php
<?php
declare(strict_types=1);
namespace App\Model;
use Nette;
use Nette\Security\Passwords;
/**
* Users management.
*/
class UserManager implements Nette\Security\IAuthenticator
{
use Nette\SmartObject;
private $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;
/** @var Passwords */
private $passwords;
public function __construct(Nette\Database\Context $database, Passwords $passwords)
{
$this->database = $database;
$this->passwords = $passwords;
}
/**
* Performs an authentication.
* @throws Nette\Security\AuthenticationException
*/
public function authenticate(array $credentials): Nette\Security\IIdentity
{
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 (!$this->passwords->verify($password, $row[self::COLUMN_PASSWORD_HASH])) {
throw new Nette\Security\AuthenticationException('The password is incorrect.', self::INVALID_CREDENTIAL);
} elseif ($this->passwords->needsRehash($row[self::COLUMN_PASSWORD_HASH])) {
$row->update([
self::COLUMN_PASSWORD_HASH => $this->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.
* @throws DuplicateNameException
*/
public function add(string $username, string $email, string $password): void
{
try {
$this->database->table(self::TABLE_NAME)->insert([
self::COLUMN_NAME => $username,
self::COLUMN_PASSWORD_HASH => $this->passwords->hash($password),
self::COLUMN_EMAIL => $email,
]);
} catch (Nette\Database\UniqueConstraintViolationException $e) {
throw new DuplicateNameException;
}
}
}
class DuplicateNameException extends \Exception
{
}
?>
SignUpFormFactory.php
<?php
namespace App\Forms;
use App\Model;
use Nette;
use Nette\Application\UI\Form;
class SignUpFormFactory
{
use Nette\SmartObject;
/** @var Model\UserManager */
private $userManager;
public function __construct(Model\UserManager $userManager)
{
$this->userManager = $userManager;
}
public function create()
{
$form = new Form; // means Nette\Application\UI\Form
$form->addText('username', 'Username:')
->setRequired();
$form->addEmail('email', 'Email:')
->setRequired();
$form->addPassword('password', 'Password:')
->setRequired();
$form->addPassword('confPassword', 'Confirm Password:')
->setRequired();
$form->addSubmit('submit', 'Sign Up');
$form->onSuccess[] = function (Form $form, \stdClass $values){
try {
$this->userManager->add($values->username, $values->email, $values->password);
} catch (Model\DuplicateNameException $e) {
$form['username']->addError('Username is already taken.');
return;
}
};
return $form;
}
}
?>
config.neon
parameters:
application:
errorPresenter: Error
mapping:
*: App\*Module\Presenters\*Presenter
session:
expiration: 14 days
services:
- App\Model\UserManager
- App\Forms\SignUpFormFactory
router: App\RouterFactory::createRouter
database:
dsn: 'mysql:host=192.168.0.106;dbname=web'
user: 'admin'
password: ''
- jiri.pudil
- Nette Blogger | 1032
Ahoj, třída Nette\Security\Passwords
je statická, takže
nevyžaduj její instanci v konstruktoru a její metody volej v kódu staticky
(Passwords::hash($password)
)
- Gappa
- Nette Blogger | 209
jiri.pudil napsal(a):
Ahoj, třída
Nette\Security\Passwords
je statická, takže nevyžaduj její instanci v konstruktoru a její metody volej v kódu staticky (Passwords::hash($password)
)
Doteď byla, ale už zdá se nebude:
Výše zmíněný kód od @KrKOo tedy nejspíš bude z masteru sandboxu nebo webprojectu.