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
Contexto y motivación del proyecto Tras 25 años gestionando infraestructuras de hosting, he identificado un…
Una reflexión para responsables de sistemas, CTOs, directores de producto y administradores con responsabilidad sobre…
Estimada empresa: Les escribo para expresar mi profundo descontento con el servicio recibido tras contratar…
En el ecosistema de la lucha contra el spam, Spamhaus es una de las organizaciones…
¡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,…