Skip to content

Commit 27aaf24

Browse files
committed
Update CMS authentication tutorial for Authentication plugin v4
- Update version requirement to ^4.0 - Use allowUnauthenticated() instead of deprecated addUnauthenticatedActions() - Use array URLs instead of Router::url() strings for better maintainability - Use setConfig() method for service configuration - Use AbstractIdentifier constants for field mapping - Use getLoginRedirect() method for handling post-login redirects - Simplify login action (remove redundant allowMethod, cleaner flash logic) - Simplify logout action (no need to check auth status first) - Update template to use Form->button() instead of Form->submit() - Fix legend text from "username" to "email" to match form field
1 parent e882d9e commit 27aaf24

File tree

1 file changed

+44
-44
lines changed

1 file changed

+44
-44
lines changed

docs/en/tutorials-and-examples/cms/authentication.md

Lines changed: 44 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ enable new users to register.
1616
Use 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
5151
namespace App\Model\Entity;
5252

53-
use Authentication\PasswordHasher\DefaultPasswordHasher; // Add this line
53+
use Authentication\PasswordHasher\DefaultPasswordHasher;
5454
use Cake\ORM\Entity;
5555

5656
class 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:
112112
use Authentication\AuthenticationService;
113113
use Authentication\AuthenticationServiceInterface;
114114
use Authentication\AuthenticationServiceProviderInterface;
115+
use Authentication\Identifier\AbstractIdentifier;
115116
use Authentication\Middleware\AuthenticationMiddleware;
116-
use Cake\Routing\Router;
117117
use Psr\Http\Message\ServerRequestInterface;
118118
```
119119

@@ -144,31 +144,42 @@ public function middleware(MiddlewareQueue $middlewareQueue): MiddlewareQueue
144144

145145
public 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

188200
Now, 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 [CakePHPs defaults on session.cookie_secure](../../development/sessions))
218+
> (See [CakePHP's defaults on session.cookie_secure](../../development/sessions))
207219
208220
In 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

219231
public 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
298303
public 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

324324
The above tells `AuthenticationComponent` that the `add()` action of the

0 commit comments

Comments
 (0)