Don't you speak portuguese? Translate this site with Google Translator

Pensamento do Dia

O rio atinge os objectivos porque aprendeu a contornar os obstáculos. (André Luiz)

13.8 - Autenticação e Autorização Simples

13.8 – Autenticação e Autorização Simples


O sucesso não consiste em não errar, mas em não cometer os mesmos equívocos mais de uma vez. (George Bernard Shaw)



Criar um aplicativo tipo blog com CakePHP 3 e autenticação simples

Tomando como ponto de partida o exemplo de aplicativo blog do site oficial do CakePHP:
https://book.cakephp.org/3.0/pt/tutorials-and-examples/blog/blog.html 


Basicamente esta parte:
https://book.cakephp.org/3.0/pt/tutorials-and-examples/blog-auth-example/auth.html 

Banco

-- Primeiro, criamos a tabela articles
CREATE TABLE articles (
    id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    title VARCHAR(50),
    body TEXT,
    created DATETIME DEFAULT NULL,
    modified DATETIME DEFAULT NULL
);

-- Então inserimos articles para testes
INSERT INTO articles (title,body,created)
    VALUES ('The title', 'This is the article body.', NOW());
INSERT INTO articles (title,body,created)
    VALUES ('A title once again', 'And the article body follows.', NOW());
INSERT INTO articles (title,body,created)
    VALUES ('Title strikes back', 'This is really exciting! Not.', NOW());

CREATE TABLE users (
    id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    username VARCHAR(50),
    password VARCHAR(255),
    role VARCHAR(20),
    created DATETIME DEFAULT NULL,
    modified DATETIME DEFAULT NULL
);

Criar aplicativo

cd varwww/html
cacomposer.phar create-project --prefer-dist cakephp/app blog

Configurar o banco em config/app.php
Configurar as rotas em config/routes.php para Users/login


Gerar o código

bin/cake bake all articles
bin/cake bake all users

Adicionar ao src/Controller/UsersController.php

use Cake\Event\Event;

    public function beforeFilter(Event $event)
    {
        parent::beforeFilter($event);
        $this->Auth->allow('add');
    }

Alterar o src/Template/Users/login.ctp, apenas a linha do username para que receba o foco automaticamente ao ser aberta:

        <?= $this->Form->input('username', ['autofocus' => true]) ?>

Adicione ao src/Controller/AppController.php, logo ao final do initialize():

        $this->loadComponent('Auth', [
            'loginRedirect' => [
                'controller' => 'Articles',
                'action' => 'index'
            ],
            'logoutRedirect' => [
                'controller' => 'Pages',
                'action' => 'display',
                'home'
            ]
        ]);

Ao final da classe:
    public function beforeFilter(Event $event)
    {
        $this->Auth->allow(['index', 'view', 'display']);
    }

Adicione ao início do src/Controller/UsersController.php

    public function beforeFilter(Event $event)
    {
        parent::beforeFilter($event);
        // Permitir aos usuários se registrarem e efetuar logout.
        // Você não deve adicionar a ação de "login" a lista de permissões.
        // Isto pode causar problemas com o funcionamento normal do AuthComponent.
        $this->Auth->allow(['add', 'logout']);
    }

    public function login()
    {
        if ($this->request->is('post')) {
            $user = $this->Auth->identify();
            if ($user) {
                $this->Auth->setUser($user);
                return $this->redirect($this->Auth->redirectUrl());
            }
            $this->Flash->error(__('Usuário ou senha ínvalido, tente novamente'));
        }
    }

    public function logout()
    {
        return $this->redirect($this->Auth->logout());
    }

Adicionar o suporte ao bcrypt para o hash das senhas

Editar src/Model/Entity/User.php e adicionar:

use Cake\Auth\DefaultPasswordHasher;

    protected function _setPassword($password)
    {
        if (strlen($password) > 0) {
            return (new DefaultPasswordHasher)->hash($password);
        }
    }

Criar o src/Template/Users/login.ctp contendo:

<div class="users form">
<?= $this->Flash->render('auth') ?>
<?= $this->Form->create() ?>
    <fieldset>
        <legend><?= __('Por favor informe seu usuário e senha') ?></legend>
        <?= $this->Form->input('username') ?>
        <?= $this->Form->input('password') ?>
    </fieldset>
<?= $this->Form->button(__('Login')); ?>
<?= $this->Form->end() ?>
</div>
Execute no mysql
ALTER TABLE articles ADD COLUMN user_id INT(11);

Edite o AppController.php e mude o Auth para:

    $this->loadComponent('Auth', [
        'authorize' => ['Controller'], // Adicione está linha
        'loginRedirect' => [
            'controller' => 'Articles',
            'action' => 'index'
        ],
        'logoutRedirect' => [
            'controller' => 'Pages',
            'action' => 'display',
            'home'
        ]
    ]);

Logo ao final:

public function isAuthorized($user)
{
    // Admin pode acessar todas as actions
    if (isset($user['role']) && $user['role'] === 'admin') {
        return true;
    }

    // Bloqueia acesso por padrão
    return false;
}

Adicione ao início do src/Controller/ArticlesController.php

    public function isAuthorized($user)
    {
        // Todos os usuários registrados podem adicionar artigos
        if ($this->request->getParam('action') === 'add') {
            return true;
        }

        // Apenas o proprietário do artigo pode editar e excluí
        if (in_array($this->request->getParam('action'), ['edit', 'delete'])) {
            $articleId = (int)$this->request->getParam('pass.0');
            if ($this->Articles->isOwnedBy($articleId, $user['id'])) {
                return true;
            }
        }

        return parent::isAuthorized($user);
    }

Adicione ao src/Model/Table/ArticlesTable.php

    public function isOwnedBy($articleId, $userId)
    {
        return $this->exists(['id' => $articleId, 'user_id' => $userId]);
    }

Acesse

http://localhost/auth_blog/users/add

Adicione um usuário

Faça login com ele
http://localhost/auth_blog

Faça logout
http://localhost/auth_blog/users/logout

Veja que ele volta para a home do controller Pages.

Vamos mudar isso para que volte para o Users/login

Altere estas linhas no AppController:

            'logoutRedirect' => [
                'controller' => 'Users',
                'action' => 'login',
                'home'
            ]

Caso já tenhamos cadastrado todos os usuários do aplicativo devemos remover o add de:

    public function beforeFilter(Event $event)
    {
        parent::beforeFilter($event);
        $this->Auth->allow(['logout']);
    }

Pronto. Nosso aplicativo agora somente será acessado por quem autorizarmos.


Bom exemplo:

https://lornajane.net/posts/2016/simple-access-control-cakephp3

 

Comments fornecido por CComment

Novo Testamento

QUAL é, pois, a vantagem do judeu? Ou qual a utilidade da circuncisão?
(Rm, 3:1)

Rotas no Mapa do Google

© 2015 Ribamar FS. All Rights Reserved. Designed By JoomShaper