Issue
Version: 4.2.9
I have followed this tutorial to setup the login. https://book.cakephp.org/authentication/2/en/index.html
The problem is, that my custom finder not gets recognized, because in the debug message I see no join to the Userdata table.
This is my query which is wrong because the Userdata table is not joined.
SELECT Users.ID AS Users__ID, Users.UUID AS Users__UUID, Users.PasswordHashed AS Users__PasswordHashed, Users.Role AS Users__Role, Users.ReleaseGroup AS Users__ReleaseGroup FROM users Users WHERE Users.email = :c0 LIMIT 1
in my UsersTable.php
public function initialize(array $config): void
{
parent::initialize($config);
$this->setTable('users');
$this->setDisplayField('ID');
$this->setPrimaryKey('ID');
$this->hasOne('Userdata');
}
public function findAuth(\Cake\ORM\Query $query, array $options) {
return $query->contain('Userdata');
}
in my UsersController.php
public function beforeFilter(\Cake\Event\EventInterface $event)
{
parent::beforeFilter($event);
// Configure the login action to not require authentication, preventing
// the infinite redirect loop issue
$this->Authentication->addUnauthenticatedActions(['login']);
}
public function login()
{
$this->request->allowMethod(['get', 'post']);
$result = $this->Authentication->getResult();
// regardless of POST or GET, redirect if user is logged in
if ($result->isValid()) {
// redirect to /articles after login success
$redirect = $this->request->getQuery('redirect', [
'controller' => 'Articles',
'action' => 'index',
]);
return $this->redirect($redirect);
}
// display error if user submitted and authentication failed
if ($this->request->is('post') && !$result->isValid()) {
$this->Flash->error(__('Invalid username or password'));
}
}
In my AppController.php
public function initialize(): void
{
parent::initialize();
$this->loadComponent('RequestHandler');
$this->loadComponent('Flash');
$this->loadComponent('Authentication.Authentication');
$this->loadComponent('Auth', [
'authorize'=> 'Controller',
'authenticate' => [
'Form' => [
'fields' => [
'username' => 'fmail',
'password' => 'password'
],
'finder' => 'auth',
]
],
//use isAuthorized in Controllers
'authorize' => ['Controller'],
// If unauthorized, return them to page they were just on
'unauthorizedRedirect' => $this->referer()
]);
In my src/Application.php
public function bootstrap(): void
{
// Call parent to load bootstrap from files.
parent::bootstrap();
$this->addPlugin('Authentication');
if (PHP_SAPI === 'cli') {
$this->bootstrapCli();
} else {
FactoryLocator::add(
'Table',
(new TableLocator())->allowFallbackClass(false)
);
}
/*
* Only try to load DebugKit in development mode
* Debug Kit should not be installed on a production system
*/
if (Configure::read('debug')) {
$this->addPlugin('DebugKit');
}
// Load more plugins here
}
public function middleware(MiddlewareQueue $middlewareQueue): MiddlewareQueue
{
$middlewareQueue
// ... other middleware added before
->add(new RoutingMiddleware($this))
// add Authentication after RoutingMiddleware
->add(new AuthenticationMiddleware($this));
return $middlewareQueue;
}
public function getAuthenticationService(ServerRequestInterface $request): AuthenticationServiceInterface
{
$authenticationService = new AuthenticationService([
'unauthenticatedRedirect' => Router::url('/users/login'),
'queryParam' => 'redirect',
]);
// Load identifiers, ensure we check email and password fields
$authenticationService->loadIdentifier('Authentication.Password', [
'fields' => [
'username' => 'email',
'password' => 'password',
],
]);
// Load the authenticators, you want session first
$authenticationService->loadAuthenticator('Authentication.Session');
// Configure form data check to pick email and password
$authenticationService->loadAuthenticator('Authentication.Form', [
'fields' => [
'username' => 'email',
'password' => 'password',
],
'loginUrl' => Router::url('/users/login'),
]);
return $authenticationService;
}
Here my question with solution for 3.x (old) CakePHP: Login over 2 tables
Solution
Thanks for the push into the right direction.
removed old loadComponent from my AppControler.php
public function initialize(): void
{
parent::initialize();
$this->loadComponent('RequestHandler');
$this->loadComponent('Flash');
$this->loadComponent('Authentication.Authentication');
/*
* Enable the following component for recommended CakePHP form protection settings.
* see https://book.cakephp.org/4/en/controllers/components/form-protection.html
*/
//$this->loadComponent('FormProtection');
}
linked the tables with custom binding/foreign-key in UsersTable.php
public function initialize(array $config): void
{
parent::initialize($config);
$this->setTable('users');
$this->setDisplayField('ID');
$this->setPrimaryKey('ID');
$this->hasOne('Userdata', [
'bindingKey' => 'UUID',
'foreignKey' => 'UUID',
]);
}
public function findForAuthentication(\Cake\ORM\Query $query, array $options): \Cake\ORM\Query
{
return $query->contain('Userdata');
}
and defined my custom resolver in my src/Application.php
// Load identifiers, ensure we check email and password fields
$authenticationService->loadIdentifier('Authentication.Password', [
'fields' => [
'username' => 'userdata.email',
'password' => 'PasswordHashed',
],
'resolver' => [
'className' => 'Authentication.Orm',
'userModel' => 'Users',
'finder' => 'forAuthentication',
],
]);
thanks
Answered By - thedoomer1000
0 Comments:
Post a Comment
Note: Only a member of this blog may post a comment.