Hey salut, bienvenue dans la suite de ce tutoriel sur Symfony. Dans la dernière partie, nous avons réussi à inscrire nos utilisateurs sur notre site à travers un formulaire d'inscription basique, avec une adresse email, un nom d'utilisateur et un mot de passe. Dans ce tutoriel, nous allons permettre à nos utilisateurs de s'authentifier sur notre site en renseignant leur adresse email et mot de passe, nous allons ensuite vérifier quel utilisateur peut ajouter un article, le modifier et aussi le supprimer. Nous allons donc commencer maintenant.
Le formulaire de connexion
Les utilisateurs qui visitent notre site doivent pouvoir s'y connecter en renseignant leur adresse email et mot de passe. Pour cela nous allons donc créer un formulaire de connexion et le traiter pour valider les informations saisis par l'utilisateur et ensuite l'identifier.
Pour créer le formulaire de connexion, nous allons utiliser la commande make:auth
de MakerBundle
(on est trop paresseux c'est vrai). Ouvrez donc un terminal et entrez la commande:
$ php bin/console make:auth
What style of authentication do you want? [Empty authenticator]:
[0] Empty authenticator
[1] Login form authenticator
> 1
The class name of the authenticator to create (e.g. AppCustomAuthenticator):
> LoginFormAuthenticator
Choose a name for the controller class (e.g. SecurityController) [SecurityController]:
>
Do you want to generate a '/logout' URL? (yes/no) [yes]:
>
created: src/Security/LoginFormAuthenticator.php
updated: config/packages/security.yaml
created: src/Controller/SecurityController.php
created: templates/security/login.html.twig
Success!
Next:
- Customize your new authenticator.
- Finish the redirect "TODO" in the App\Security\LoginFormAuthenticator::onAuthenticationSuccess() method.
- Review & adapt the login template: templates/security/login.html.twig.
Des questions vont donc vous être posées:
- La première question c'est de savoir quel type d'authenticator vous voulez créer? Vous choisissez
Login form authenticator
, vous saisissez 1 puisentrer
- Puis il faut saisir le nom de la classe qui va servir d'authenticator, moi j'ai choisi
LoginFormAuthenticator
vous pouvez en faire de même ou choisir un nom qui vous va le mieux - Ensuite le nom du contrôleur, par défaut il vous propose
SecurityController
, vous pouvez saisir ce que vous voulez ou juste appuyer surEntrer
si vous voulez utiliserSecurityController
- Enfin, est-ce que nous voulons d'une route pour la déconnexion, bien sur, on saisit donc
yes
Cette commande va générer 3 nouveaux fichiers:
LoginFormAuthenticator.php
danssrc/Security/
ce fichier est celui qui s'occupe d'aller récupérer l'utilisateur dans la base données, en fonction de l'email qu'il a renseigner, vérifier que le mot de passe est conforme à celui enregistrer, ... Si vous regarder son contenu vous verrez tout ce qu'il permet de faire.SecurityController.php
danssrc/Controller/
, c'est dans ce fichier que les contrôleurs pour la connexionlogin()
et la déconnexionlogout()
sont défini.login.html.twig
danstemplates/security/
c'est la vue qui affiche le formulaire de connexion.
La commande a aussi modifier le fichier security.yaml
qui se trouve dans config/packages/
et y a rajouter l'authenticator et une entrée pour le logout
. Je vous laisse découvrir cela.
Rendez-vous sur http://127.0.0.1:8000/login et en temps normal vous devez avoir le formulaire de connexion qui s'affiche.
Si vous avez utiliser les mêmes blocs que moi, vous risquez de ne pas voir le formulaire s'afficher, le même problème que nous avions avec la page d'inscription.
Nous allons pour commencer ouvrir le fichier login.html.twig
, il ressemble à ceci:
{# templates/security/login.html.twig #}
{% extends 'base.html.twig' %}
{% block title %}Log in!{% endblock %}
{% block body %}
<form method="post">
{% if error %}
<div class="alert alert-danger">{{ error.messageKey|trans(error.messageData, 'security') }}</div>
{% endif %}
{% if app.user %}
<div class="mb-3">
You are logged in as {{ app.user.username }}, <a href="{{ path('app_logout') }}">Logout</a>
</div>
{% endif %}
<h1 class="h3 mb-3 font-weight-normal">Please sign in</h1>
<label for="inputEmail">Email</label>
<input type="email" value="{{ last_username }}" name="email" id="inputEmail" class="form-control" required autofocus>
<label for="inputPassword">Password</label>
<input type="password" name="password" id="inputPassword" class="form-control" required>
<input type="hidden" name="_csrf_token"
value="{{ csrf_token('authenticate') }}"
>
{#
Uncomment this section and add a remember_me option below your firewall to activate remember me functionality.
See https://symfony.com/doc/current/security/remember_me.html
<div class="checkbox mb-3">
<label>
<input type="checkbox" name="_remember_me"> Remember me
</label>
</div>
#}
<button class="btn btn-lg btn-primary" type="submit">
Sign in
</button>
</form>
{% endblock %}
Je vais juste le modifier un petit peu pour avoir le design que je souhaite pour mon application.
Et voici mon nouveau fichier login.html.twig
:
{# templates/security/login.html.twig #}
{% extends 'base.html.twig' %}
{% block title %}Connexion{% endblock %}
{% block content %}
<div class="container center">
<h1>Connexion</h1>
<form method="post" class="row">
{% if error %}
<div class="col s12 m6 l6 offset-m3 offset-l3">
<span class="error">{{ error.messageKey|trans(error.messageData, 'security') }}</span>
</div>
{% endif %}
{% if app.user %}
<div class="col s12 m6 l6 offset-m3 offset-l3">
Tu es actuellement connecté en tant que {{ app.user.username }}, <a href="{{ path('app_logout') }}">Déconnecte-toi</a>
</div>
{% endif %}
<div class="input-field col s12 m6 l6 offset-m3 offset-l3">
<input type="email" value="{{ last_username }}" name="email" id="inputEmail" class="" required autofocus placeholder="Adresse email">
</div>
<div class="input-field col s12 m6 l6 offset-m3 offset-l3">
<input type="password" name="password" id="inputPassword" class="form-control" required placeholder="Mot de passe">
</div>
<input type="hidden" name="_csrf_token" value="{{ csrf_token('authenticate') }}">
{#
Uncomment this section and add a remember_me option below your firewall to activate remember me functionality.
See https://symfony.com/doc/current/security/remember_me.html
<div class="checkbox mb-3">
<label>
<input type="checkbox" name="_remember_me"> Remember me
</label>
</div>
#}
<div class="input-field col s12">
<input type="submit" class="btn btn-primary" value="Me connecter">
</div>
</form>
</div>
{% endblock %}
Et ma page de connexion http://127.0.0.1:8000/login s'affiche comme ceci:
Avant de procéder à la connexion, nous avons juste un dernier détail à régler, quand l'utilisateur se connecte avec succès, il faut que nous le redirigeons vers la page d'accueil, pour cela, nous allons ouvrir le fichier LoginFormAuthenticator.php
qui se trouve dans src/Security/
et modifier la fonction onAuthenticationSuccess()
comme ceci:
<?php
// src/Security/LoginFormAuthenticator.php
namespace App\Security;
use App\Entity\User;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface;
use Symfony\Component\Security\Core\Exception\CustomUserMessageAuthenticationException;
use Symfony\Component\Security\Core\Exception\InvalidCsrfTokenException;
use Symfony\Component\Security\Core\Security;
use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Security\Core\User\UserProviderInterface;
use Symfony\Component\Security\Csrf\CsrfToken;
use Symfony\Component\Security\Csrf\CsrfTokenManagerInterface;
use Symfony\Component\Security\Guard\Authenticator\AbstractFormLoginAuthenticator;
use Symfony\Component\Security\Http\Util\TargetPathTrait;
class LoginFormAuthenticator extends AbstractFormLoginAuthenticator
{
use TargetPathTrait;
private $entityManager;
private $urlGenerator;
private $csrfTokenManager;
private $passwordEncoder;
public function __construct(EntityManagerInterface $entityManager, UrlGeneratorInterface $urlGenerator, CsrfTokenManagerInterface $csrfTokenManager, UserPasswordEncoderInterface $passwordEncoder)
{
$this->entityManager = $entityManager;
$this->urlGenerator = $urlGenerator;
$this->csrfTokenManager = $csrfTokenManager;
$this->passwordEncoder = $passwordEncoder;
}
// ...
public function onAuthenticationSuccess(Request $request, TokenInterface $token, $providerKey)
{
if ($targetPath = $this->getTargetPath($request->getSession(), $providerKey)) {
return new RedirectResponse($targetPath);
}
return new RedirectResponse($this->urlGenerator->generate('homepage'));
}
// ..
}
Vous pouvez maintenant vous rendre sur la page de connexion et vous connecter. Si c'est bon vous êtes automatiquement rediriger vers la page d'accueil et votre adresse email est afficher dans la debug bar.
Juste une chose sur la barre de navigation, nous allons retirer le lien Login et le remplacer par Logout quand l'utilisateur est connecté. La barre de navigation se trouve dans le fichier base.html.twig
:
{# templates/base.html.twig #}
<!DOCTYPE html>
<html>
<head>
<title>{% block title %}Symfony Blog{% endblock %}</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
{% block stylesheets %}
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/css/materialize.min.css">
<link rel="stylesheet" type="text/css" href="{{ asset('assets/css/app.css') }}">
{% endblock %}
</head>
<body>
<nav>
<div class="nav-wrapper">
<div class="container">
<a href="{{ path('homepage') }}" class="brand-logo">Symfony Blog</a>
<ul id="nav-mobile" class="right hide-on-med-and-down">
<li><a href="{{ path('homepage') }}">Home</a></li>
{% if app.user %}
<li><a href="/logout">Logout</a></li>
{% else %}
<li><a href="/login">Login</a></li>
{% endif %}
</ul>
</div>
</div>
</nav>
{% block content %}
{% endblock %}
{% block scripts %}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.0/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/js/materialize.min.js"></script>
<script type="text/javascript">
$('select').formSelect();
</script>
{% endblock %}
</body>
</html>
Sur la ligne 22, je vérifie juste si un objet user existe, si c'est le cas, c'est qu'un utilisateur est connecté j'affiche donc le lien de déconnexion, sinon j'affiche le lien de connexion.
Vous pouvez cliquer sur Logout pour vous déconnecter et Login pour vous connecter.
Pour récupérer l'utilisateur connecté dans une vue twig vous faites {{ app.user }}
, et vous pouvez accéder à tous ses attributs comme son email avec {{ app.user.email }}
. Si vous êtes dans un controlleur qui hérite de la classe AbstractController
de Symfony, pour récupérer l'utilisateur connecté vous faites $this->getUser()
. Là aussi vous pouvez avoir son adresse email avec $this->getUser()->getEmail()
.
Créer un espace d'administration
Nous allons maintenant créer un espace d'administration. Pour cela nous allons:
- Créer une route
/admin
dansconfig/routes.yaml
- Créer un contrôleur
admin()
danssrc/Controller/BlogController.php
- Et enfin créer la vue
index.html.twig
danstemplates/admin/
qui va afficher la liste des tutoriels et utilisateurs
Je vous pari que vous saurez le faire, on en a déjà parler dans les tutoriels précédents. Essayez et vous verrez.
Voici mon fichier routes.yaml
:
# config/routes.yaml
homepage:
path: /
controller: App\Controller\BlogController::index
article_add:
path: /add
controller: App\Controller\BlogController::add
article_show:
path: /show/{url}
controller: App\Controller\BlogController::show
article_edit:
path: /edit/{id}
controller: App\Controller\BlogController::edit
requirements:
id: '\d+'
article_remove:
path: /remove/{id}
controller: App\Controller\BlogController::remove
requirements:
id: '\d+'
admin:
path: /admin
controller: App\Controller\BlogController::admin
Le contrôleur admin()
dans le fichier BlogController.php
// src/Controller/BlogController.php
<?php
namespace App\Controller;
use App\Entity\User;
use App\Entity\Article;
use App\Form\ArticleType;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
class BlogController extends AbstractController
{
// ...
public function admin()
{
$articles = $this->getDoctrine()->getRepository(Article::class)->findBy(
[],
['lastUpdateDate' => 'DESC']
);
$users = $this->getDoctrine()->getRepository(User::class)->findAll();
return $this->render('admin/index.html.twig', [
'articles' => $articles,
'users' => $users
]);
}
// ...
}
Je récupère la liste de tous les articles et des utilisateurs que je renvoie à la vue. Le code de la vue:
{# templates/admin/index.html.twig #}
{% extends "base.html.twig" %}
{% block title %}Admin. | {{ parent() }}{% endblock %}
{% block content %}
<div class="admin-page">
<div class="container">
<div class="row">
<div class="col s12">
<a href="{{ path('article_add') }}" class="btn btn blue darken-4" style="float: right">Ajouter</a>
<h5>Articles</h5>
<table>
<tr>
<th>#</th>
<th>Titre</th>
<th>Publier</th>
<th>Date de publication</th>
<th>Date de modification</th>
<th>Actions</th>
</tr>
{% set i = 1 %}
{% for article in articles %}
<tr>
<td>{{ i }}</td>
<td><a href="{{ path('article_show', {'url': article.url}) }}" target="_blank">{{ article.title }}</a></td>
<td>
<span class="badge {{ article.isPublished ? 'blue' : 'red' }}">
{{ article.isPublished ? 'oui' : 'non' }}
</span>
</td>
<td>{{ article.isPublished ? article.publicationDate|date('d/m/Y') : '-' }}</td>
<td>{{ article.lastUpdateDate|date('d/m/Y') }}</td>
<td>
<a href="{{ path('article_edit', {'id': article.id}) }}"><i class="material-icons blue-text">edit</i></a>
<a href="{{ path('article_remove', {'id': article.id}) }}"><i class="material-icons red-text">delete</i></a>
</td>
</tr>
{% set i = i+1 %}
{% endfor %}
</table>
</div>
</div>
<div class="row">
<div class="col s12 m-t-30">
<h5>Utilisateurs</h5>
<table>
<tr>
<th>#</th>
<th>Adresse email</th>
<th>Username</th>
<th>Roles</th>
<th>Actions</th>
</tr>
{% set i = 1 %}
{% for user in users %}
<tr>
<td>{{ i }}</td>
<td>{{ user.email }}</td>
<td>{{ user.username }}</td>
<td>
<span class="badge blue">
admin.
</span>
</td>
<td>
<a href=""><i class="material-icons red-text">delete</i></a>
</td>
</tr>
{% set i = i+1 %}
{% endfor %}
</table>
</div>
</div>
</div>
</div>
{% endblock %}
Et ce qui donne la page suivante:
J'utilise principalement materializecss sur cette application et aussi material icons pour les icônes.
Si vous accédez maintenant au lien http://127.0.0.1:8000/admin vous devez normalement voir votre espace d'administration. Bravo.
Interdire l'accès à l'administration
Maintenant que nous avons notre espace d'administration, nous allons interdire l'accès à cet espace. Si vous remarquez bien à ce niveau, tout le monde peut y accéder, même si vous êtes pas connecté.
Chaque utilisateur authentifié sur Symfony a par défaut le rôle ROLE_USER
. On peut à notre tour créé les rôles que nous souhaitons, c'est juste des chaînes de caractères qui doivent commencer par ROLE_
puis le nom de votre rôle par exemple ROLE_ADMIN
, ROLE_EDITOR
, ... le tout en majuscule. Pour attribuer un rôle à un utilisateur, nous ajoutons juste le rôle aux tableaux $roles[]
de l'objet User
. Nous verrons cela sous peu.
Nous allons donc interdire l'accès à l'espace d'administration a une personne qui n'est pas connecter et qui n'a pas le rôle ROLE_ADMIN
. Pour cela, nous pouvons soit définir un contrôle d'accès dans le fichier config/packages/security.yaml
ou directement dans le contrôleur.
Définir un contrôle d'accès dans security.yaml
Nous allons utiliser cette méthode généralement pour protéger une route ou un ensemble de route.
Si nous voulons par exemple interdire l'accès à la route /admin
:
# config/packages/security.yaml
security:
# ...
access_control:
- { path: ^/admin, roles: ROLE_ADMIN }
Si vous essayez maintenant d'acceder à http://127.0.0.1:8000/admin vous êtes automatiquement rediriger vers la page de connexion, pour vous dire de vous connecter avant d'y accéder.
Ce que nous faisons ici au fait, c'est que nous disons: toutes les routes qui commencent (^
) par admin
requiert le rôle ROLE_ADMIN
. Ceci est donc valable pour /admin/users
, /admin/articles
, mais pas /home/admin
, il faut forcément que la route commence par admin
juste après la racine.
Je vous invite à donc vous connecter et essayez encore une fois d'accéder à l'espace d'administration http://127.0.0.1:8000/admin vous allez avoir une erreur Access Denied (accès refusé).
Ce qui s'est passé, c'est que le système vous a déjà authentifier, vous essayez ensuite d'accéder a une page alors que votre rôle ne vous le permet pas, logique qu'on vous refuse l'accès. Nous allons donc nous ajouter ce ROLE_ADMIN
.
Ajouter un rôle à un utilisateur
Nous allons créer une commande Symfony pour nous permettre d'ajouter un rôle à n'importe quel utilisateur en renseignant juste son adresse email et le rôle que nous voulons lui rajouter. Mais avant, nous allons rajouter une méthode addRoles()
dans la classe User.php
qui se situe dans src/Entity
, cette fonction va prendre en paramètre un rôle et l'ajouter au tableau $roles[]
de l'utilisateur.
<?php
// src/Entity/User.php
namespace App\Entity;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
use Symfony\Component\Security\Core\User\UserInterface;
/**
* @ORM\Entity(repositoryClass="App\Repository\UserRepository")
* @UniqueEntity(fields={"email"}, message="Un utilisateur existe déjà avec cette adresse email.")
*/
class User implements UserInterface
{
/**
* @ORM\Id()
* @ORM\GeneratedValue()
* @ORM\Column(type="integer")
*/
private $id;
// ...
public function addRoles(string $roles): self
{
if (!in_array($roles, $this->roles)) {
$this->roles[] = $roles;
}
return $this;
}
// ...
}
Pour créer une commande console avec Symfony, vous faites juste make:command
comme ceci:
$ php bin/console make:command
Le système va alors vous demander de renseigner le nom de votre commande, moi j'ai choisi app:user:promote
.
Un nouveau fichier UserPromoteCommand.php
va donc être creer dans src/Command/
, c'est dans ce fichier que va être défini les paramètres de la commande, comment est-ce qu'elle va fonctionner, ... Je vous invite à lire la documentation pour en apprendre plus.
J'ai apporter quelques modifications au contenu du fichier UserPromoteCommand.php
, voici le resultat final:
<?php
// src/Command/UserPromoteCommand.php
namespace App\Command;
use App\Entity\User;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Style\SymfonyStyle;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
class UserPromoteCommand extends Command
{
protected static $defaultName = 'app:user:promote';
private $om;
public function __construct(EntityManagerInterface $om)
{
$this->om = $om;
parent::__construct();
}
protected function configure()
{
$this
->setDescription('Promote a user by adding him a new roles.')
->addArgument('email', InputArgument::REQUIRED, 'Email address of the user you want to promote.')
->addArgument('roles', InputArgument::REQUIRED, 'The roles you want to add to the user.')
;
}
protected function execute(InputInterface $input, OutputInterface $output): int
{
$io = new SymfonyStyle($input, $output);
$email = $input->getArgument('email');
$roles = $input->getArgument('roles');
$userRepository = $this->om->getRepository(User::class);
$user = $userRepository->findOneByEmail($email);
if ($user) {
$user->addRoles($roles);
$this->om->flush();
$io->success('The roles has been successfully added to the user.');
} else {
$io->error('There is no user with that email address.');
}
return 0;
}
}
Notre commande prend deux paramètres:
- L'adresse email de l'utilisateur auquel on veut rajouter un rôle
- Le rôle que l'on veut rajouter à l'utilisateur
Si l'adresse email n'existe pas, une erreur lui est renvoyer pour dire que l'utilisateur n'existe pas
Sinon le rôle est ajouté à l'utilisateur
Pour utiliser la commande:
$ php bin/console app:user:promote aliou@kaherecode.com ROLE_ADMIN
Et c'est tout.
Je vais juste me déconnecter puis me reconnecter pour que le nouveau rôle puisse entrer en vigueur. Et si j'essaie d'acceder à http://127.0.0.1:8000/admin ça marche bien.
Interdire l'accès directement dans le contrôleur
La deuxième méthode pour contrôler les accès consiste à définir l'accès directement dans le contrôleur.
Pour interdire l'accès au contrôleur d'ajout d'un article a une personne qui n'a pas le role ROLE_ADMIN
, nous allons faire:
<?php
// src/Controller/BlogController.php
namespace App\Controller;
// ...
class BlogController extends AbstractController
{
// ...
public function add(Request $request)
{
$this->denyAccessUnlessGranted('ROLE_ADMIN');
$article = new Article();
$form = $this->createForm(ArticleType::class, $article);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$article->setLastUpdateDate(new \DateTime());
$article->setUrl($this->generateSlug($article->getTitle()));
if ($article->getPicture() !== null) {
$file = $form->get('picture')->getData();
$fileName = uniqid(). '.' .$file->guessExtension();
try {
$file->move(
$this->getParameter('images_directory'),
$fileName
);
} catch (FileException $e) {
return new Response($e->getMessage());
}
$article->setPicture($fileName);
}
if ($article->getIsPublished()) {
$article->setPublicationDate(new \DateTime());
}
$em = $this->getDoctrine()->getManager();
$em->persist($article);
$em->flush();
return $this->redirectToRoute('admin');
}
return $this->render('blog/add.html.twig', [
'form' => $form->createView()
]);
}
// ...
}
Dans la contrôleur add()
, on appelle la methode denyAccessUnlessGranted()
et en paramètre on lui donne le rôle requis pour accéder à ce contrôleur.
Nous pouvons aussi utiliser les annotations pour contrôler l'accès à un contrôleur:
<?php
// src/Controller/BlogController.php
namespace App\Controller;
// ..
use Sensio\Bundle\FrameworkExtraBundle\Configuration\IsGranted;
class BlogController extends AbstractController
{
// ..
/**
* @IsGranted("ROLE_ADMIN")
*/
public function edit(Article $article, Request $request)
{
$oldPicture = $article->getPicture();
$form = $this->createForm(ArticleType::class, $article);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$article->setLastUpdateDate(new \DateTime());
if (!$article->getIsPublished()) {
$article->setUrl($this->generateSlug($article->getTitle()));
}
if ($article->getIsPublished()) {
$article->setPublicationDate(new \DateTime());
}
if ($article->getPicture() !== null && $article->getPicture() !== $oldPicture) {
$file = $form->get('picture')->getData();
$fileName = uniqid(). '.' .$file->guessExtension();
try {
$file->move(
$this->getParameter('images_directory'),
$fileName
);
} catch (FileException $e) {
return new Response($e->getMessage());
}
$article->setPicture($fileName);
} else {
$article->setPicture($oldPicture);
}
$em = $this->getDoctrine()->getManager();
$em->persist($article);
$em->flush();
return $this->redirectToRoute('admin');
}
return $this->render('blog/edit.html.twig', [
'article' => $article,
'form' => $form->createView()
]);
}
// ...
}
Et voilà, pour accéder à la méthode edit()
il faut avoir le rôle ROLE_ADMIN
.
Et dans la vue, nous pouvons aussi contrôler le rôle de la personne connecter en utilisant la méthode is_granted()
, cela va nous permettre d'afficher ou pas des sections de notre page en fonction du rôle de l'utilisateur:
{# templates/base.html.twig #}
{# ... #}
<body>
<nav>
<div class="nav-wrapper">
<div class="container">
<a href="{{ path('homepage') }}" class="brand-logo">Symfony Blog</a>
<ul id="nav-mobile" class="right hide-on-med-and-down">
<li><a href="{{ path('homepage') }}">Home</a></li>
{% if app.user %}
{% if is_granted('ROLE_ADMIN') %}
<li><a href="/admin">Admin.</a></li>
{% endif %}
<li><a href="/logout">Logout</a></li>
{% else %}
<li><a href="/login">
Participe à la discussion