CakePHP 3 autentykacja

W tej części zajmiemy się tym co bardzo często pojawia się w aplikacjach www czyli autentykacją. Dodamy zatem akcje logowania i wylogowania. W pliku src/Controller/AppController.php w funkcji initialize dodajemy komponent Auth.

$this->loadComponent('Auth', [
	'authorize' => 'Controller',
	'unauthorizedRedirect' => $this->referer(),
]);
$this->Auth->allow(['display', 'password', 'reset', 'logout']);//do tych akcji jest dostę dla każdego
Komponent Auth ma wiele opcji konfiguracyjnych. Poniżej bardziej rozbudowana konfiguracja, w której definiujemy model obsługujący autentykację użytkowników. Pola używane do logowania (w poniższym przykładzie email i password). Ponadto można zdefiniować akcje logowania, akcję, na którą nastąpi przekierowanie po zalogowaniu, akcję, na którą nastąpi przekierowanie po wylogowaniu, teksty błędów. W poniższym przykładzie użyto również w konfiguracji klucza finder. Opiszę go później.
$this->loadComponent('Auth',[
	'loginAction' => [
		'controller' => 'Adminusers',
		'action' => 'login',
		'prefix' => 'admin'
	],
	'loginRedirect' => [
		'controller' => 'Home',
		'action' => 'index',
		'prefix' => 'admin'
	],
	'logoutRedirect' => [
		'controller' => 'Home',
		'action' => 'index',
		'prefix' => false
	],
	'authError' => 'Brak uprawnień',
	'loginError' => 'Podaj poprawne dane logowania',
	'authenticate' => [
		'Form',
		AuthComponent::ALL => [
			'userModel'=>'Adminusers',
			'fields'=> [
				'username'=>'email',
				'password'=>'password'
			],
			'finder' => 'active'
		]
	],
	'authorize'=>'Controller'
]);
My pozostaniemy na razie przy domyślnych ustawieniach z pierwszego listingu. Jako klasa nadrzędna AppController kontroluje kto ma być autoryzowany dla wszystkich kontrolerów. Domyślnym ustawieniem jest ustawienie, że zalogowany użytkownik jest autoryzowany wszędzie, anonimowi użytkownicy nigdzie. Aby to zmienić, dodajemy funkcję isAuthorized() w pliku AppController.php.
public function isAuthorized($user)
{
	if (in_array($user['role'], ['Admin', 'User']) { // Nie dawaj dostępu do wyłączonych kont
		return true;
	}
	return false;
}
Powinienieś nie mieć dostępu do akcji /users/index lub /users/add z przeglądarki. Teraz pozostało nam jeszcze utworzenie akcji login w kontrolerze src/Controller/UsersController.php oraz odpowiedniego widoku.
public function login()
{
	if ($this->request->is('post')) {
		$user = $this->Auth->identify();
		if ($user && $user['role'] != 'Disabled') { // Nie zezwalamy na logowanie użytkownikom "Disabled"
			$this->Auth->setUser($user);
			return $this->redirect($this->Auth->redirectUrl());
		}
		$this->Flash->error('Your username or password is incorrect.');
	}
}
Utwórz plik src/Template/Users/login.ctp z następującą treścią.
<?php $this->assign('title', 'Login'); ?>
<div class="users form">
    <?php echo $this->Form->create() ?>
    <fieldset>
        <legend>
        <?php echo $this->Form->input('username', ['autofocus' => true]) ?>
        <?php echo $this->Form->input('password') ?>
        <?php echo $this->Html->link(__('Forgot Password?'), ['action' => 'password']) ?>
    </fieldset>
    <?php echo $this->Form->button(__('Login')); ?>
    <?php echo $this->Form->end() ?>
</div>
Teraz można już się logować wchodząc na stronę http://localhost/users/login. Możemy w konfiguracji komponentu Auth użyć własnego findera, który wybierze użytkownika do autentykacji. W ten sposób w poniższym przykładzie zalogować będą się mogli tylko użytkownicy, których pole deleted w bazie jest równe 0.
W konfiguracji komponentu:
public function initialize()
{
    parent::initialize();
    $this->loadComponent('Auth', [
        'authenticate' => [
            'Form' => [
                'finder' => 'active'
            ]
        ],
    ]);
}
W pliku tabeli UsersTable.php piszemy findera findActive, który modyfikuje zapytanie do bazy o dodatkowy warunek.
public function findActive(\Cake\ORM\Query $query, array $options)
{
	$query
		->select()
		->where(['Users.deleted' => 0]);
	return $query;
}