Ahora veremos como hacer un login y registro con Symfony2. En el post anterior definimos la plantilla en la que montamos el formulario de login. ¡OJO! Con el name de username y password en el formulario de login, es necesario que delante tengan un guión bajo.
Ahora montaremos el sistema de autenticación que nos proporciona Symfony2.
Definiremos las rutas que necesitaremos hasta ahora en el fichero routing.yml de nuestro bundle:
inicio: pattern: / defaults: { _controller: WebBlogBundle:Posts:index, page:1 } home: pattern: /inicio/{page} defaults: { _controller: WebBlogBundle:Posts:index, page:1 } registro: pattern: /registro defaults: { _controller: WebBlogBundle:Default:index } #Rutas para la autenticacion login: pattern: /login defaults: { _controller: WebBlogBundle:Default:login } login_check: pattern: /login_check logout: pattern: /logout
Ahora configuraremos el fichero app/config/security.yml, aquí cofiguramos las entidades y las rutas que entran en juego en la autenticación y tambien la ACL de Symfony. En nuestro caso lo dejaremos así:
security: firewalls: identificarse: pattern: ^/* anonymous: ~ provider: users form_login: login_path: login check_path: /login_check logout: path: logout target: / providers: users: entity: { class: Web\BlogBundle\Entity\Users, property: email } access_control: - { path: ^/registro, roles: IS_AUTHENTICATED_ANONYMOUSLY} encoders: Web\BlogBundle\Entity\Users: { algorithm: sha512, iterations: 10 }
El siguiente paso es modificar la entidad para que funcione automáticamente con el componente de seguridad. Modificamos el fichero src/Web/BlogBundle/Entity/Users.php y añadimos lo siguiente.
<?php namespace Web\BlogBundle\Entity; use Doctrine\ORM\Mapping as ORM; use Doctrine\Common\Collections\ArrayCollection; use Symfony\Component\Security\Core\User\UserInterface; /** * Users */ class Users implements UserInterface { //Implementacion de la interfaz de roles public function equals(UserInterface $users){ return $this->getEmail()==$users->getUsername(); } public function eraseCredentials() { return false; } public function getRoles() { //return array("ROLE_USUARIO"); return array($this->getRole()); } public function getUsername() { return $this->getEmail(); } public function getSalt() { return false; } //Fin de la definicion de clases de la interface de roles
Ahora crearemos el formulario de registro. Web\BlogBundle\Form\Type\RegistroType.php
<?php namespace Web\BlogBundle\Form\Type; use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\FormBuilderInterface; use Doctrine\ORM\EntityRepository; class RegistroType extends AbstractType { public function buildForm(FormBuilderInterface $builder, array $options) { $builder->add('name', 'text', array("label" => "Nombre: ", "required" => false, "attr" => array('class' => 'form-control'))) ->add('surname', 'text', array("label" => "Apellido: ", "required" => false, "attr" => array('class' => 'form-control'))) ->add('email', 'email', array("label" => "Correo electronico: ", "required" => false, "attr" => array('class' => 'form-control'))) ->add('password', 'repeated', array( 'type' => 'password', 'invalid_message' => 'Las contraseñas no son iguales, repitelo', 'required' => true, 'first_options' => array('label' => 'Contraseña: ',"attr" => array('class' => 'form-control')), 'second_options' => array('label' => 'Repetir contraseña: ',"attr" => array('class' => 'form-control')))) ->add('Registrarse', 'submit',array("attr" => array('class' => 'btn btn-success'))); } public function getName() { return 'Registro'; } } ?>
Para hacer el login y registro en Symfony2 utilizaremos DefaultController.php
<?php namespace Web\BlogBundle\Controller; use Symfony\Bundle\FrameworkBundle\Controller\Controller; use Web\BlogBundle\Entity\Users; use Web\BlogBundle\Form\Type\RegistroType; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Session\Session; use Symfony\Component\Security\Core\SecurityContext; use Symfony\Component\Security\Core\Exception\AccessDeniedException; class DefaultController extends Controller { private $session; public function __construct() { //Cargamos el componente de sesion en todos los metodos $this->session = new Session(); } public function indexAction(Request $request) { //Instanciamos el obejeto usuario $user = new Users(); //Creamos el formulario de Registro $registro_form = $this->createForm(new RegistroType(), $user); //Recogemos los datos $registro_form->handleRequest($request); //Si el formulario está enviado if ($registro_form->isSubmitted()) { //Consigue los datos $nombre = $registro_form->get('name')->getData(); $apellidos = $registro_form->get('surname')->getData(); $email = $registro_form->get('email')->getData(); //Cifra la contraseña $factory = $this->get('security.encoder_factory'); $encoder = $factory->getEncoder($user); $password = $encoder->encodePassword($registro_form->get('password')->getData(), $user->getSalt()); //Seteamos los atributos $user->setName($nombre); $user->setSurname($apellidos); $user->setEmail($email); $user->setPassword($password); $user->setDescription("Describete"); $user->setImage("default_avatar.png"); $user->setRole("ROLE_USUARIO"); } //Si el formulario es valido if ($registro_form->isValid()) { $repositorio = $this->getDoctrine()->getRepository('WebBlogBundle:Users'); $email_existe = false; if ($email_existe == false) { //Guarda el usuario en base de datos $em = $this->getDoctrine()->getManager(); $persist = $em->persist($user); $flush = $em->flush(); //generar flasdata $this->session->getFlashBag()->add('info', '¡Enhorabuena! Te has registrado correctamente'); //Redirigir return $this->redirect($this->generateURL('registro')); } else { //genera una sesion flasdata $this->session->getFlashBag()->add('info', 'Email o nick duplicado intentalo de nuevo'); } } //Categorias $em = $this->getDoctrine()->getEntityManager(); $categoryRepository=$em->getRepository("WebBlogBundle:Categories"); $categories=$categoryRepository->findAll(); //Renderizar vista y pasar formulario return $this->render('WebBlogBundle:Default:registro.html.twig', array('registro_form' => $registro_form->createView(), "categories"=>$categories )); } public function loginAction(Request $request){ // Si la autenticación falla que nos lleve a registro y si no a la home if($this->session->get(SecurityContext::AUTHENTICATION_ERROR)){ $this->session->getFlashBag()->add('login', 'Introduce unas credenciales correctas'); return $this->redirect($this->generateURL('registro')); }else{ if($this->get('security.context')->isGranted('ROLE_USUARIO')){ return $this->redirect($this->generateURL('home')); } } } }
La vista de registro src/Web/BlogBundle/Resources/views/Default/registro.html.twig hereda de la plantilla y quedaría así:
{% extends "::plantilla.html.twig" %} {%block categorias%} {% for category in categories %} <li><a href="#">{{ category.name }}</a></li> {% endfor %} {%endblock%} {% block content %} <div class="col-lg-8 col-md-8 col-sm-8 col-xs-8"> <h3>Registrate</h3> <hr/> {% for mensaje in app.session.flashbag().get('info') %} <p class="info">{{ mensaje }}</p> {% endfor %} <form action="" method="post" {{ form_enctype(registro_form) }}> {{ form_widget(registro_form) }} {{ form_errors(registro_form) }} </form> </div> {%endblock%}
Con esto ya tendríamos el login y registro en Symfony2.