Symfony 4 / Sonata: Tạo xác thực frontend

Để sử dụng bảng khác từ bảng mặc định cho việc xác thực,

Đầu tiên, chúng ta cần tạo thực thể của mình để quản lý người dùng của mình.

Thực thể này sau đó cần được triển khai để UserInterface.

Vì vậy, chúng ta cần thêm tham chiếu đến thành phần và triển khai nó:

<?php

namespace App\Entity;

use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\ORM\Mapping\Entity;
use Doctrine\ORM\Mapping\Table;
use Doctrine\ORM\Mapping\Id;
use Doctrine\ORM\Mapping\Column;
use Doctrine\ORM\Mapping\GeneratedValue;
use Doctrine\ORM\Mapping\Index;
use Symfony\Component\Security\Core\User\UserInterface;

/**
 * @ORM\Entity(repositoryClass="App\Repository\WcoconRepository")
 * @Table(name="wcocon")
 */
class Wcocon implements UserInterface
{

Bây giờ thực thể là một triển khai của UserInterface, chúng ta cần thêm các phương thức triển khai.

    
    /*Authentication méthods implements interface User*/
    public function getRoles(){
        return ['ROLE_USER'];
    }
    

    public function getPassword(){
        return $this->getWcoPassword();
    }

    public function getSalt() {
        return false;
    }
    

    public function getUsername(){
        return $this->getWcoDossier();
    }
    

    public function eraseCredentials(){
        
    }
    

Chức năng getRoles mặc định nên trả về một mảng các vai trò. Ở đây là 'ROLE_USER' nhưng chúng ta có thể thêm logic phức tạp hơn ở đây.

Tiếp theo, chúng ta cần tạo bộ điều khiển sẽ xử lý việc xác thực của chúng ta.
Sử dụng các lệnh CLI, chỉ cần chạy: php bin/console make:controller
Và tạo SecurityController của chúng ta.

Sélection_038

Trong base.html.twig của chúng ta (/templates/base.html.twig), chúng ta sẽ tạo một khối đăng nhập, sẽ là nơi đặt form của chúng ta

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>{% block title %}Welcome!{% endblock %}</title>
        <link href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">
        <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.bundle.min.js" integrity="sha384-6khuMg9gaYr5AxOqhkVIODVIvm9ynTT5J4V1cfthmT+emCG6yVmEZsRHdxlotUnm" crossorigin="anonymous"></script>
        {% block stylesheets %}{% endblock %}
    </head>
    <body>
    
        <div class="container">
          <div class="row">
            <div class="col-sm-3">
                {% block login %}{% endblock %}
            </div>
            <div class="col-sm-9"> 
                {% block body %}{% endblock %}
            </div>
        
          </div>
        </div>    
        {% block javascripts %}{% endblock %}
    </body>
</html>

Và chúng ta sẽ tạo mẫu form đăng nhập của chúng ta trong /var/www/cfc/delef/templates/security/login.html.twig.
Đây là một phần mở rộng của html cơ bản của chúng ta và cho khối đăng nhập của chúng ta:

{% extends 'base.html.twig' %}

{% block login %}
	<h1>Connexion !</h1>
	<form action="{{ path('security_login') }}" method="post">
    	<div class="form-group">
    		<input placeholder="N° de dosser" 	required name="_username" type="text" 		class="form-control">
    	<div class="form-group">
    	</div>
    		<input placeholder="password" 		required name="_password" type="password" 	class="form-control">
    	</div>
    	<div class="form-group">
    		<button type="submit" class="btn btn-success">Connexion</button>
    	</div>
	</form>
{% endblock %}

Tại giai đoạn này, chúng ta có hiển thị sau:

Sélection_040

Chú ý, form đăng nhập phải chứa các trường _username và _password.

Sau đó, chúng ta cần cấu hình bộ mã hóa, sau đó là nhà cung cấp và tường lửa.
Lưu ý rằng bộ mã hóa cho văn bản thông thường là "plaintext". sẽ tốt hơn nếu sử dụng bcrypt hoặc sha khác.

security:
    encoders:
        App\Entity\Wcocon:
            algorithm: plaintext
    providers:
        frontend_users:
            entity:
              class: App\Entity\Wcocon
              property: wco_dossier
    firewalls:
        main:
            anonymous: true
            provider: frontend_users
            form_login:
                login_path: security_login
                check_path: security_login

Toàn bộ tệp trông như thế này:

security:
    # https://symfony.com/doc/current/security.html#where-do-users-come-from-user-providers
    encoders:
        FOS\UserBundle\Model\UserInterface: bcrypt
        App\Entity\Wcocon:
            algorithm: plaintext
    providers:
        in_memory: { memory: null }
        fos_userbundle:
            id: fos_user.user_provider.username
        frontend_users:
            entity:
              class: App\Entity\Wcocon
              property: wco_dossier
        



    firewalls:
        # Disabling the security for the web debug toolbar, the profiler and Assetic.
        dev:
            pattern:  ^/(_(profiler|wdt)|css|images|js)/
            security: false

        # -> custom firewall for the admin area of the URL
        admin:
            pattern:            /admin(.*)
            context:            user
            form_login:
                provider:       fos_userbundle
                login_path:     /admin/login
                use_forward:    false
                check_path:     /admin/login_check
                failure_path:   null
            logout:
                path:           /admin/logout
                target:         /admin/login
            anonymous:          true

        # -> end custom configuration

        # default login area for standard users

        # This firewall is used to handle the public login area
        # This part is handled by the FOS User Bundle
        main:
            anonymous: true
            provider: frontend_users
            form_login:
                login_path: security_login
                check_path: security_login
            
    # Easy way to control access for large sections of your site
    # Note: Only the *first* access control that matches will be used
    access_control:
        # Admin login page needs to be accessed without credential
        - { path: ^/admin/login$, role: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/admin/logout$, role: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/admin/login_check$, role: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/admin/resetting, role: IS_AUTHENTICATED_ANONYMOUSLY }

        # Secured part of the site
        # This config requires being logged for the whole site and having the admin role for the admin part.
        # Change these rules to adapt them to your needs
        - { path: ^/admin/, role: [ROLE_ADMIN, ROLE_SONATA_ADMIN, ROLE_SUPER_ADMIN] }
        - { path: ^/.*, role: IS_AUTHENTICATED_ANONYMOUSLY }

Sau đó, chúng ta cần cấu hình url đăng xuất của mình.
Để làm điều này, chúng ta phải thêm một tuyến đường trong bộ điều khiển của mình và đăng ký nó trong cấu hình.

Trong bộ điều khiển thêm phương thức:

    /**
     * @Route("/deconnexion", name="security_logout")
     */    
    public function logout(){}

Và trong cấu hình:
Path đề cập đến tuyến đường, và target cho phép bạn đưa ra url chuyển hướng một khi xác thực được đặt lại.

        main:
            anonymous: true
            provider: frontend_users
            form_login:
                login_path: security_login
                check_path: security_login
            logout:
                path: security_logout
                target: /