@@ -16,7 +16,7 @@ enable new users to register.
1616Use composer to install the Authentication Plugin:
1717
1818``` bash
19- composer require " cakephp/authentication:~3 .0"
19+ composer require " cakephp/authentication:^4 .0"
2020```
2121
2222### Adding Password Hashing
@@ -50,15 +50,15 @@ add the following:
5050<?php
5151namespace App\Model\Entity;
5252
53- use Authentication\PasswordHasher\DefaultPasswordHasher; // Add this line
53+ use Authentication\PasswordHasher\DefaultPasswordHasher;
5454use Cake\ORM\Entity;
5555
5656class User extends Entity
5757{
5858 // Code from bake.
5959
6060 // Add this method
61- protected function _setPassword(string $password) : ?string
61+ protected function _setPassword(string $password): ?string
6262 {
6363 if (mb_strlen($password) > 0) {
6464 return (new DefaultPasswordHasher())->hash($password);
@@ -112,8 +112,8 @@ In **src/Application.php**, add the following imports:
112112use Authentication\AuthenticationService;
113113use Authentication\AuthenticationServiceInterface;
114114use Authentication\AuthenticationServiceProviderInterface;
115+ use Authentication\Identifier\AbstractIdentifier;
115116use Authentication\Middleware\AuthenticationMiddleware;
116- use Cake\Routing\Router;
117117use Psr\Http\Message\ServerRequestInterface;
118118```
119119
@@ -144,31 +144,42 @@ public function middleware(MiddlewareQueue $middlewareQueue): MiddlewareQueue
144144
145145public function getAuthenticationService(ServerRequestInterface $request): AuthenticationServiceInterface
146146{
147- $authenticationService = new AuthenticationService([
148- 'unauthenticatedRedirect' => Router::url('/users/login'),
147+ $service = new AuthenticationService();
148+
149+ // Define where users should be redirected to when they are not authenticated
150+ $service->setConfig([
151+ 'unauthenticatedRedirect' => [
152+ 'prefix' => false,
153+ 'plugin' => null,
154+ 'controller' => 'Users',
155+ 'action' => 'login',
156+ ],
149157 'queryParam' => 'redirect',
150158 ]);
151159
152- // Load the authenticators, you want session first
153- $authenticationService->loadAuthenticator('Authentication.Session');
154- // Configure form data check to pick email and password
155- $authenticationService->loadAuthenticator('Authentication.Form', [
156- 'fields' => [
157- 'username' => 'email',
158- 'password' => 'password',
160+ $fields = [
161+ AbstractIdentifier::CREDENTIAL_USERNAME => 'email',
162+ AbstractIdentifier::CREDENTIAL_PASSWORD => 'password',
163+ ];
164+
165+ // Load the authenticators. Session should be first.
166+ $service->loadAuthenticator('Authentication.Session');
167+ $service->loadAuthenticator('Authentication.Form', [
168+ 'fields' => $fields,
169+ 'loginUrl' => [
170+ 'prefix' => false,
171+ 'plugin' => null,
172+ 'controller' => 'Users',
173+ 'action' => 'login',
159174 ],
160- 'loginUrl' => Router::url('/users/login'),
161175 'identifier' => [
162176 'Authentication.Password' => [
163- 'fields' => [
164- 'username' => 'email',
165- 'password' => 'password',
166- ],
177+ 'fields' => $fields,
167178 ],
168179 ],
169180 ]);
170181
171- return $authenticationService ;
182+ return $service ;
172183}
173184```
174185
@@ -183,6 +194,7 @@ public function initialize(): void
183194
184195 // Add this line to check authentication result and lock your site
185196 $this->loadComponent('Authentication.Authentication');
197+ }
186198```
187199
188200Now, on every request, the ` AuthenticationMiddleware ` will inspect
@@ -203,7 +215,7 @@ If you visit your site, you'll get an "infinite redirect loop" so let's fix that
203215> If your application serves from both SSL and non-SSL protocols, then you might have problems
204216> with sessions being lost, in case your application is on non-SSL protocol. You need to enable
205217> access by setting session.cookie_secure to false in your config/app.php or config/app_local.php.
206- > (See [ CakePHP’ s defaults on session.cookie_secure] ( ../../development/sessions ) )
218+ > (See [ CakePHP' s defaults on session.cookie_secure] ( ../../development/sessions ) )
207219
208220In your ` UsersController ` , add the following code:
209221
@@ -213,25 +225,18 @@ public function beforeFilter(\Cake\Event\EventInterface $event): void
213225 parent::beforeFilter($event);
214226 // Configure the login action to not require authentication, preventing
215227 // the infinite redirect loop issue
216- $this->Authentication->addUnauthenticatedActions (['login']);
228+ $this->Authentication->allowUnauthenticated (['login']);
217229}
218230
219231public function login()
220232{
221- $this->request->allowMethod(['get', 'post']);
222233 $result = $this->Authentication->getResult();
223- // regardless of POST or GET, redirect if user is logged in
234+ // If the user is logged in send them away.
224235 if ($result && $result->isValid()) {
225- // redirect to /articles after login success
226- $redirect = $this->request->getQuery('redirect', [
227- 'controller' => 'Articles',
228- 'action' => 'index',
229- ]);
230-
231- return $this->redirect($redirect);
236+ $target = $this->Authentication->getLoginRedirect() ?? ['controller' => 'Articles', 'action' => 'index'];
237+ return $this->redirect($target);
232238 }
233- // display error if user submitted and authentication failed
234- if ($this->request->is('post') && !$result->isValid()) {
239+ if ($this->request->is('post')) {
235240 $this->Flash->error(__('Invalid username or password'));
236241 }
237242}
@@ -241,16 +246,16 @@ Add the template logic for your login action:
241246
242247``` php
243248<!-- in /templates/Users/login.php -->
244- <div class =" users form" >
249+ <div class =" users form content " >
245250 <?= $this->Flash->render() ?>
246251 <h3 >Login</h3 >
247252 <?= $this->Form->create() ?>
248253 <fieldset >
249- <legend ><?= __('Please enter your username and password') ?></legend >
254+ <legend ><?= __('Please enter your email and password') ?></legend >
250255 <?= $this->Form->control('email', ['required' => true]) ?>
251256 <?= $this->Form->control('password', ['required' => true]) ?>
252257 </fieldset >
253- <?= $this->Form->submit (__('Login')); ?>
258+ <?= $this->Form->button (__('Login')); ?>
254259 <?= $this->Form->end() ?>
255260
256261 <?= $this->Html->link("Add User", ['action' => 'add']) ?>
@@ -274,7 +279,7 @@ public function beforeFilter(\Cake\Event\EventInterface $event): void
274279 parent::beforeFilter($event);
275280 // for all controllers in our application, make index and view
276281 // actions public, skipping the authentication check
277- $this->Authentication->addUnauthenticatedActions (['index', 'view']);
282+ $this->Authentication->allowUnauthenticated (['index', 'view']);
278283}
279284```
280285
@@ -297,13 +302,8 @@ Add the logout action to the `UsersController` class:
297302// in src/Controller/UsersController.php
298303public function logout()
299304{
300- $result = $this->Authentication->getResult();
301- // regardless of POST or GET, redirect if user is logged in
302- if ($result && $result->isValid()) {
303- $this->Authentication->logout();
304-
305- return $this->redirect(['controller' => 'Users', 'action' => 'login']);
306- }
305+ $this->Authentication->logout();
306+ return $this->redirect(['controller' => 'Users', 'action' => 'login']);
307307}
308308```
309309
@@ -318,7 +318,7 @@ sign up for our application. In the `UsersController` fix the following line:
318318
319319``` php
320320// Add to the beforeFilter method of UsersController
321- $this->Authentication->addUnauthenticatedActions (['login', 'add']);
321+ $this->Authentication->allowUnauthenticated (['login', 'add']);
322322```
323323
324324The above tells ` AuthenticationComponent ` that the ` add() ` action of the
0 commit comments