IMPORTANT: Per accedir als fitxer de subversion: http://acacha.org/svn (sense password). Poc a poc s'aniran migrant els enllaços. Encara però funciona el subversion de la farga però no se sap fins quan... (usuari: prova i la paraula de pas 123456)

Laravel Socialite és una fluent API que proporciona una interfície per l'autenticació amb OAuth i serveis de Login de xarxes socials com Facebook, Twitter, Google, LinkedIn, GitHub o Bitbucket. Permet evitar tenir que escriure tot el codi boilerplate que se sol necessitar per dur a terme social authentication a una aplicació Laravel.

Requeriments

Resum de com funciona OAuth

  • Un usuari visita una pàgina de la vostra aplicació (Laravel) que requereix d'autenticació i el reenvieu a la pàgina de Login
  • La pàgina de Login us pot reenviar directament al que s'anomena el vostre proveïdor de servei d'autenticació (per exemple Github) o pot tenir una botó tipus "Login with Github"
  • El usuari visita una pàgina del proveïdor del servei d'autenticació (a l'exemple Github) i aquest s'encarrega d'autenticar l'usuari. (el desenvolupador prèviament a configurat una aplicació de Github)
  • Un cop el Login al proveïdor de servei és correcte el proveidor crida una URL anomenada callback URL que correspon a una pàgina de la nostra aplicació. Juntament amb l'execució de la URL de callback el proveïdor ens proporciona un token que identifica l'usuari. Aquesta URL de callback la hem configurat prèviament en el moment que hem creat l'aplicació de Github
  • La nostra aplicació (consuming application) utilitza el Token per obtenir la informació personal de l'usuari de Github.GitHub. Aquest informació es pot utilitzar per crear un compte d'usuari i logar l'usuari.

Per a més informació llegiu l'article OAuth

Recursos:

Instal·lació i configuració

Utilitzeu composer per afegir Socialite al vostre projecte Laravel:

$ composer require laravel/socialite

I per configurar Socialite primer com amb tot paquet Laravel heu d'instal·lar el Laravel Service Provider del paquet Socialite afegint la línia:

Laravel\Socialite\SocialiteServiceProvider::class

Al fitxer config/app.php. Un exemple:

'providers' => [
    // Other service providers...

    Laravel\Socialite\SocialiteServiceProvider::class,
],

També cal afegir la Laravel Facade Socialite al array alias:

'Socialite' => Laravel\Socialite\Facades\Socialite::class,

I finalment cal afegir les credencials de OAuth del servei o serveis que vulgueu utilitzar al fitxer de configuració config/services.php. Un exemple amb Github:

'github' => [
    'client_id' => 'your-github-app-id',
    'client_secret' => 'your-github-app-secret',
    'redirect' => 'http://your-callback-url',
],

El millor que podeu fer si es tracta d'un projecte OPen Source i no voleu publicar dades confidencials és:

'github' => [
    'client_id' => env('GITHUB_ID'),
    'client_secret' => env('GITHUB_SECRET'),
    'redirect' => env('GITHUB_URL'),
],

I posar les dades al fitxer d'environment .env:

GITHUB_ID=client id from github
GITHUB_SECRET=client secret from github
GITHUB_URL=http://mysocialiteapplication.app:8000/auth/github/callback

Ara ja esteu preparats per utilitzar la llibreria.

Configuració de routes

Haureu d'afegir com a mínim dos rutes:

  Route::get('auth/github', 'Auth\AuthController@redirectToProvider');
  Route::get('auth/github/callback', 'Auth\AuthController@handleProviderCallback');

Proveïdors de servei autenticació

Github

Cal crear una nova aplicació que utilitzi Oauth amb Github a:

https://github.com/settings/applications/new

Heu de tenir un compte de Github.

NOTA: A diferència d'altres serveis més restrictius si que podeu fer redireccions a URLs en desenvolupament o locals, però també heu de tenir en compte que haureu de tornar a omplir el formulari i canviar les URLs quan passeu a explotació

El més important del formulari és la URL de callback que és la URL per a la qual haureu de crear un controlador que gestioni el retorn a la vostra aplicació un cop feta l'autenticació a Github.

Vegeu també:

Socialite providers

Com funciona?

API

La interfície pública o API de la llibreria està definida pels contractes que podeu trobar a:

https://github.com/laravel/socialite/tree/master/src/Contracts

Aquesta API com altres APIs a Laravel utilitza una part molt concreta del framework Laravel també coneguda com llibreria de suport ( Vegeu Illuminate/support [1]) i més concretament la classe Abstracta Manager Illuminate\Support\Manager ([2]) que ens permet treballar amb múltiples proveïdors de servei d'autenticació als qual Laravel anomena drivers. Vegem con funciona:

La interfície:

Laravel\Socialite\Contracts\Factory ([3])

Té uns sol mètode com a contracte (entenem com a contracte el pacte que han de firmar les entitats (classes) que vulguin utilitzar Socialite):

 public function driver($driver = null);

Bàsicament el que farem amb socialite és utilitzar la Facade Socialite de la següent forma:

Socialite::driver('github')

o

Socialite::driver('facebook')

També podem utilitzar la injecció de dependències amb injecció de dependències a un mètode:


 public function unMetodeDunControladorLaravelQualsevol(Laravel\Socialite\Contracts\Factory $socialite){
    $socialite->driver('github')
 }

o injecció de dependències al constructor:


 protected $socialite;
 
 public function __constructor(Laravel\Socialite\Contracts\Factory $socialite){
  $this->socialite = $socialite;
}

 public function unMetodeDunControladorLaravelQualsevol(){
    $this->socialite->driver('github')
 }

Per tant si us fixeu el primer que farem és indicar amb quin proveïdor de servei d'autenticació volem treballar, i com en moltes altres APIs de Laravel això s'implementa utilitzant el concepte de driver. Per a l'API socialite nosaltres podem canviar de driver (proveïdor de servei d'autenticació) però la interfície o API pública que utilitzarem per a programar el nostre codi no dependrà del driver. Això és així per què si us fixeu en la classe SocialiteServiceProvider ([4]) al mètode register registrem amb un singleton quina implementació específica de la interfície Laravel\Socialite\Contracts\Factory utilitzem

public function register()
    {
        $this->app->singleton('Laravel\Socialite\Contracts\Factory', function ($app) {
            return new SocialiteManager($app);
        });
    }

La classe escollida és SocialiteManager [5]. Si us fixeu aquesta classe NO implementa el contracte (no implementa el mètode driver) sinó que és el seu pare la classe Manager ([6]) qui ho implementa. Bàsicament la classe Illuminate\Support\Manager proporciona les eines necessàries per treballar amb drivers. Si mireu els mètodes driver i createDriver:


/**
     * Get a driver instance.
     *
     * @param  string  $driver
     * @return mixed
     */
    public function driver($driver = null)
    {
        $driver = $driver ?: $this->getDefaultDriver();
        // If the given driver has not been created before, we will create the instances
        // here and cache it so we can return it next time very quickly. If there is
        // already a driver created by this name, we'll just return that instance.
        if (! isset($this->drivers[$driver])) {
            $this->drivers[$driver] = $this->createDriver($driver);
        }
        return $this->drivers[$driver];
    }
    /**
     * Create a new driver instance.
     *
     * @param  string  $driver
     * @return mixed
     *
     * @throws \InvalidArgumentException
     */
    protected function createDriver($driver)
    {
        $method = 'create'.Str::studly($driver).'Driver';
        // We'll check to see if a creator method exists for the given driver. If not we
        // will check for a custom driver creator, which allows developers to create
        // drivers using their own customized driver creator Closure to create it.
        if (isset($this->customCreators[$driver])) {
            return $this->callCustomCreator($driver);
        } elseif (method_exists($this, $method)) {
            return $this->$method();
        }
        throw new InvalidArgumentException("Driver [$driver] not supported.");
    }

Permeten a la classe filla implementar tants drivers com vulgui simplement creant mètodes amb el nom create + NomDelDriverAmbStudlyCaps + Driver com per exemple:

createGithubDriver
createFacebookDriver
createGoogleDriver
createLinkedinDriver
createBitbucketDriver

Que són els drivers que implementa Socialite per defecte. Podeu trobar implementacion de més drivers a http://socialiteproviders.github.io/. De fet observeu que seria senzill implementar més drivers simplement fent una classe filla de SocialiteManager, creant un mètode createMyDriverDriver i canviant el mètode register del SocialiteServiceProvider (o crear el vostre propi ServiceProvider).

En tot cas sigui quin sigui el driver els mètodes encarregats de crear el driver el que retornen sempre és un objecte que compleix amb la interfície/contracte Laravel\Socialite\Contracts\ProviderDriver([7]) que defineix la API de socialite la qual és molt bàsica i té dos mètodes:



<?php
namespace Laravel\Socialite\Contracts;
interface Provider
{
    /**
     * Redirect the user to the authentication page for the provider.
     *
     * @return \Symfony\Component\HttpFoundation\RedirectResponse
     */
    public function redirect();
    /**
     * Get the User instance for the authenticated user.
     *
     * @return \Laravel\Socialite\Contracts\User
     */
    public function user();
}
  • Mètode redirect: és el mètode encarregat de enviar l'usuari que està intentant fer un Social Login al proveïdor de servei escollit
  • Mètode user: permet obtenir les dades de l'usuari proveïdes per proveïdor de servei d'autenticació

Observant el contracte que han d'implementar tots els objectes User tornats pels proveïdors de servei podreu saber quina informació tindreu disponible. Vegeu:

https://github.com/laravel/socialite/blob/master/src/Contracts/User.php

Els mètodes són:

  • getId(): identificador de l'usuari al proveïdor de servei
  • getNickname(): el nom d'usuari o username
  • getName(): Nom complet.
  • getEmail(): email de l'usuari
  • getAvatar(): avatar de l'usuari

Finalment podeu veure la implementació dels proveïdors de servei a les carpetes:

https://github.com/laravel/socialite/tree/master/src/One
https://github.com/laravel/socialite/tree/master/src/Two

Lo de One i Two fa referència a una classificació dels serveis segons suportin OAuth v1 o v2.

Per exemple Github:

https://github.com/laravel/socialite/blob/master/src/Two/GithubProvider.php

On podeu observar que com tots els proveïdors de servei implementa el contracte Provider i hereta de la classe AbstractProvider:

https://github.com/laravel/socialite/blob/master/src/Two/AbstractProvider.php

Què és el lloc on posem tot el codi comú dels proveïdors de servei per tal de tenir un codi DRY.

Acacha Socialite Package

Noms:

  • AcachaSocialiteServiceProvider el service provider
  • AcachaSocialite la facade

Lògica de negoci basada en:

https://mattstauffer.co/blog/using-github-authentication-for-login-with-laravel-socialite

Però per a diferents providers (exemple només és de github) amb cody DRY.

Tests:

https://laracasts.com/series/russian-doll-caching-in-laravel/episodes/6

Comandes php artisan:

La idea és permetre crear directament els botons de login a la pàgina de login i registre. Opcions:

  • Projecte Laravel buit: no instal·lar res per tant opcional el tema d'instal·lar vistes, qui vulgui es faci els seus propis links
  • Projecte Laravel amb php artisan make:auth instal·lat: opció 1. Instal·lar unes adaptacions (stubs) del projecte Laravel però amb els botons. Comanda: php artisan make:socialaauth
  • Projecte Laravel amb [adminlte-laravel]] instal·lat: opció 2: no ho faria en aquest paquet sinó que els faria tots dos compatibles és a dir que acacha-adminlte-laravel ja portes els botons apuntant a les URLs d'aquest paquet. Per tant no cal comanda php artisan

Proveïdors vull proporcionar de sèrie:

  • Facebook
  • Twitter
  • Google
  • Github: prioritari

Notes:

  • Dependrà de Socialite: no fer cap tasca que ja faci Socialite
  • Facilitarà les tasques que cal fer amb cada projecte que utilitzi Socialite
  • Instal·lació de les rutes
  • Executar un mètode d'una facade per instal·lar les routes com Route::auth() però utilitzant la nostra pròpia facade?
  • L'esquema serà idèntic per a tots els proveïdors per tant definir un array de proveïdors suportats i recorrer l'array
  • Configuració
  • Permetre afegir proveïdors als proveïdors de sèrie
  • Esquema de la URL configurable: per defecte auth/{provider}/auth i auth/{provider}/callback però poder canviar prefix auth
  • Un sol controlador/ruta amb provider com a variable

Web i documentació dels proveidors

Github

Heu d'anar a la URL:

https://github.com/settings/applications/new

Facebook

Heu d'anar a la URL:

https://developers.facebook.com/apps/

Google

Heu d'anar a la URL:

https://console.developers.google.com

Crear unes credencials i també cal activar l'API google+ api.


Twitter

IMPORTANT: Cal activar el permis per obtenir els emails a la pestanya permissions (i obliga a posar URL condicions i web) . Obsolet: Twitter no proporciona el email dels seus usuaris via OAuth excepte si ompliu formulari: https://support.twitter.com/forms/platform

Heu d'anar a la URL:

https://apps.twitter.com/

Callback URL:

No li agrada localhost però podeu utilitzar:

http://127.0.0.1:8000/auth/twitter/callback

Vegeu:

http://stackoverflow.com/questions/800827/twitter-oauth-callbackurl-localhost-development

Vegeu també

Enllaços externs