sábado, 21 de noviembre de 2015

9 - Tutorial de Laravel 5 - Mail User (Confirmar cuenta de usuario)




Bienvenid@s a otro capítulo del Tutorial de Laravel 5, en esta ocasión vamos a programar el envío de correos de confirmación de cuenta para los usuarios que se quieran registrar a nuestra aplicación, nos basaremos en el formulario de registro del capítulo anterior.

Lo primero que haremos es configurar los datos de acceso a un servidor smtp como puede ser gmail, para ello necesitamos tener una cuenta de gmail.

Abrimos el archivo .env y modificamos las siguientes variables:

MAIL_DRIVER=smtp
MAIL_HOST=smtp.gmail.com
MAIL_PORT=587
MAIL_USERNAME=tuemail@gmail.com
MAIL_PASSWORD=tupassword
MAIL_ENCRYPTION=tls


Para lo siguiente vamos a la carpeta "config" y abrimos el archivo mail.php y modificamos las siguientes variables:

'host' => env('MAIL_HOST', 'smtp.gmail.com'),

'from' => ['address' => 'tuemail@gmail.com', 'name' => 'El nombre de la aplicación'],


Lo siguiente que haremos es importar la clase Mail en el controlador AuthController, más información sobre la clase Mail:

use Mail;


Y modificar el método postRegister para poder enviar el email de confirmación al usuario:

    public function postRegister(Request $request){
        
        $rules = [
            'name' => 'required|min:3|max:16|regex:/^[a-záéíóúàèìòùäëïöüñ\s]+$/i',
            'email' => 'required|email|max:255|unique:users,email',
            'password' => 'required|min:6|max:18|confirmed',
        ];
        
        $messages = [
            'name.required' => 'El campo es requerido',
            'name.min' => 'El mínimo de caracteres permitidos son 3',
            'name.max' => 'El máximo de caracteres permitidos son 16',
            'name.regex' => 'Sólo se aceptan letras',
            'email.required' => 'El campo es requerido',
            'email.email' => 'El formato de email es incorrecto',
            'email.max' => 'El máximo de caracteres permitidos son 255',
            'email.unique' => 'El email ya existe',
            'password.required' => 'El campo es requerido',
            'password.min' => 'El mínimo de caracteres permitidos son 6',
            'password.max' => 'El máximo de caracteres permitidos son 18',
            'password.confirmed' => 'Los passwords no coinciden',
        ];
        
        $validator = Validator::make($request->all(), $rules, $messages);
        
        if ($validator->fails()){
            return redirect("auth/register")
            ->withErrors($validator)
            ->withInput();
        }
        else{
            $user = new User;
            $data['name'] = $user->name = $request->name;
            $data['email'] = $user->email = $request->email;
            $user->password = bcrypt($request->password);
            $user->remember_token = str_random(100);
            $data['confirm_token'] = $user->confirm_token = str_random(100);
            $user->save();
            
            Mail::send('mails.register', ['data' => $data], function($mail) use($data){
                $mail->subject('Confirma tu cuenta');
                $mail->to($data['email'], $data['name']);
            });
            
            return redirect("auth/register")
            ->with("message", "Hemos enviado un enlace de confirmación a su cuenta de correo electrónico");
        }         
        
    }


A continuación crearemos la plantilla de email, para ello crearemos una carpeta llamada "mails" en la carpeta "views" y crearemos un archivo php con el siguiente nombre register.blade.php y le agregamos el siguiente código que contiene el enlace de confirmación:


<h1>Bienvenid@ {{$data['name']}}</h1>
<a href="{{url()}}/auth/confirm/email/{{$data['email']}}/confirm_token/{{$data['confirm_token']}}">Confirmar mi cuenta</a>


Como podéis ver en el enlace hemos creado la ruta que utilizaremos para confirmar la cuenta de usuario, pasando dos argumentos email y confirm_token, ahora crearemos esta ruta en el archivo routes.php:

Route::get('auth/confirm/email/{email}/confirm_token/{confirm_token}', 'Auth\AuthController@confirmRegister');


Como podéis ver esta ruta esta conectada al controlador AuthController y tiene una acción llamada confirmRegister, esta acción será la encargada de verificar o no la cuenta del usuario, así que creamos esta nueva acción en el controlador AuthController:

 public function confirmRegister($email, $confirm_token){
  $user = new User;
  $the_user = $user->select()->where('email', '=', $email)
    ->where('confirm_token', '=', $confirm_token)->get();
  
  if (count($the_user) > 0){
   $active = 1;
   $confirm_token = str_random(100);
   $user->where('email', '=', $email)
   ->update(['active' => $active, 'confirm_token' => $confirm_token]);
   return redirect('auth/register')
   ->with('message', 'Enhorabuena ' . $the_user[0]['name'] . ' ya puede iniciar sesión');
  }
  else
  {
   return redirect('');
  }
 }


 En esta acción lo primero que hacemos es una consulta select en la tabla users para comprobar si hay un usuario con el email y confirm_token pasados como argumentos en la ruta, de ser así se actualiza la columna active = 1 indicando que este usuario ha confirmado su cuenta, también se modifica el confirm_token del usuario y se redirecciona al formulario de registro con un mensaje flash.

Una vez que el usuario ha confirmado su cuenta, podéis ver como se actualizar el confirm_token, de este modo el enlace queda inhabilitado para confirmar a un nuevo usuario, de hecho si el usuario ya ha confirmado su cuenta y vuelve a hacer click en el enlace será redireccionado a la página de inicio.