Laravel dispone de un paquete oficial, llamado Laravel Socialite que nos ofrece una vía rápida y fácil, para ofrecer una forma de autentificación con proveedores de OAuth, soportando de forma oficial a la fecha, Facebook, Twitter, LinkedIn, Google, GitHub y Bitbucket. Puede ser extendido con facilidad implementando el paquete Socialite Providers
Contenidos
Primero debemos crear nuestra app en la página para desarrolladores de facebook
Después, nos saltamos el asistente, y directamente iremos a Configuración > Básica, eligiendo como origen de nuestra app el modo Web donde obtendremos dos datos necesarios, el App ID y el App Secret
También necesitamos configurar la URIs autorizadas para el retorno de los datos de la conexión. Para ello, acudiremos a Productos haciendo click sobre el símbolo ⊕ que nos desplegará la configuración del cliente OAuth
En la casilla Valid OAuth Redirect URIs, deberemos poner las dos url de retorno o callbacks autorizadas. La de desarrollo (develop) y la de producción.
composer require laravel/socialite
El fichero de configuración es config/services.php
donde añadiremos la configuración OAuth de Facebook,
return [ [...] // Otros servicios 'facebook'=> [ 'client_id' => env('FACEBOOK_CLIENT_ID', '189649333579187'), 'client_secret' => env('FACEBOOK_CLIENT_SECRET', '533d1c34e3821f965897xc595c3eee22'), 'redirect' => env('FACEBOOK_REDIRECT', 'https://conta.castris.com/login/facebook/callback') ], ]
y en nuestro fichero .env
podemos poner según la configuración usada arriba, el valor apropiado para la url de callback, según estemos o no en desarrollo.
[...] // Otros variables en el env FACEBOOK_REDIRECT=https://contacastris.test/login/facebook/callback
Dado que es un ejemplo rápido de Laravel, vamos a realizar una modificación sobre la plantilla blade que se encarga del acceso, resources/views/auth/login.blade.
php
@extends('layouts.app') @section('content') <div class="container"> <div class="row justify-content-center"> <div class="col-md-8"> <div class="card"> <div class="card-header">{{ __('Login') }}</div> <div class="card-body"> <form method="POST" action="{{ route('login') }}"> @csrf <div class="form-group row"> <label for="email" class="col-sm-4 col-form-label text-md-right">{{ __('E-Mail Address') }}</label> <div class="col-md-6"> <input id="email" type="email" class="form-control{{ $errors->has('email') ? ' is-invalid' : '' }}" name="email" value="{{ old('email') }}" required autofocus> @if ($errors->has('email')) <span class="invalid-feedback" role="alert"> <strong>{{ $errors->first('email') }}</strong> </span> @endif </div> </div> <div class="form-group row"> <label for="password" class="col-md-4 col-form-label text-md-right">{{ __('Password') }}</label> <div class="col-md-6"> <input id="password" type="password" class="form-control{{ $errors->has('password') ? ' is-invalid' : '' }}" name="password" required> @if ($errors->has('password')) <span class="invalid-feedback" role="alert"> <strong>{{ $errors->first('password') }}</strong> </span> @endif </div> </div> <div class="form-group row"> <div class="col-md-6 offset-md-4"> <div class="form-check"> <input class="form-check-input" type="checkbox" name="remember" id="remember" {{ old('remember') ? 'checked' : '' }}> <label class="form-check-label" for="remember"> {{ __('Remember Me') }} </label> </div> </div> </div> <div class="form-group row mb-0"> <div class="col-md-8 offset-md-4"> <button type="submit" class="btn btn-primary"> {{ __('Login') }} </button> <a class="btn btn-link" href="{{ route('password.request') }}"> {{ __('Forgot Your Password?') }} </a> </div> </div> </form> </div> </div> <div class="card"> <div class="card-header">Login with Facebook</div> <div class="card-body"> <a class="btn btn-primary" href="/login/facebook"> Facebook Login </a> </div> </div> </div> </div> </div> @endsection
Necesitamos definir las rutas y métodos para autentificarnos con Facebook, y lo hacemos modificando:
# Socialite facebook Route::get('/login/facebook', 'Auth\LoginController@redirectToFacebookProvider'); Route::get('login/facebook/callback', 'Auth\LoginController@handleProviderFacebookCallback'); # End Socialite facebook
Añadimos los use para Socialite
y Auth
y los dos métodos
/** * Redirecciona al usuario a la página de Facebook para autenticarse * * @return \Illuminate\Http\Response */public function redirectToFacebookProvider() { return Socialite::driver('facebook')->redirect(); } /** * Obtiene la información de Facebook * * @return \Illuminate\Http\RedirectResponse */public function handleProviderFacebookCallback() { $auth_user = Socialite::driver('facebook')->user(); // Fetch authenticated user dd($auth_user); }
dd()
(dump and die) con el fin de ver el retorno de la autentificación, que noes será útilpara conocer como trabaja, y para seguir con nuestro código con mas claridadAhora, cuando el usuario haga click en el botón de Login de Facebook, es redirigido a su página de acceso y después de confirmar los datos, será devuelta la información en dirección a la URI de callback la cual llamará al método handleProviderFacebookCallback(
)
.
Necesitamos realizar un cambio en la tabla users, y como se supoen que estamos a 0 en nuestra app, y que podemos ejecutar una migración desde 0 usando php artisan migrate:fresh
modificaremos el fichero databases/migrations/XXXX_create_users_table.php
public function up() { Schema::create('users', function (Blueprint $table) { $table->increments('id'); $table->string('name'); $table->string('email')->unique(); $table->timestamp('email_verified_at')->nullable(); $table->string('password')->nullable(); // Lo cambiamos nullable $table->rememberToken(); $table->string('token')->nullable(); // Oauth token $table->timestamps(); }); }
Una vez modificado ejecutaremos
php artisan migrate:fresh
Ahora que ya tenemos los campos necesarios, podemos continuar el código que habíamos dejado parado con el dd($auth_user)
;
public function handleProviderFacebookCallback() { $auth_user = Socialite::driver('facebook')->user(); // Fetch authenticated user $user = User::updateOrCreate( [ 'email' => $auth_user->email ], [ 'token' => $auth_user->token, 'name' => $auth_user->name ] ); Auth::login($user, true); return redirect()->to('/'); }
No olvidemos que estamos usando Eloquent, con el método updateOrCreate()
para crear o actualizar un usuario. Este método, verificará la existencia de un usuario con el email que se presenta en el primer argumento, y en caso de exista, actualizará el token y su nombre, y caso contrario, insertará un nuevo usuario con los datos, incluido el email.
Si olvidamos añadir el campo token
al atributo $fillable
de nuestro modelo User, se producirá una excepción.
protected $fillable = [ 'name', 'email', 'password', 'token' ]
La lectura del artículo Laravel Social Authtentication with Socialite, que encontré mientras busca la forma de implementar en mi aplicación de contabilidad, la forma de acceder a mi cuenta de SAGE y su API 3.1. Pero eso será otra historia.
Comparte este articulo en
¡Hola a todos! Vamos a sumergirnos en el fascinante mundo de Mod Security y aprender…
Ya son muchos años en el sector, muchos años pasando por varios paneles de control,…
La lista UCEPROTECT es una herramienta utilizada por muchos administradores de sistemas y proveedores de…
No es la primera vez que me encuentro con el agotamiento de la memoria en…
Descubre cómo solucionar problemas de acceso a servidores con Centos 7, Almalinux 8, Ubuntu 20.04…
Uno de los mensajes más alarmantes que puedes encontrarte es aquel que indica que tu…