Advertisement
  1. Code
  2. PHP

Configure un servidor OAuth2 usando el pasaporte en Laravel

Scroll to top
Read Time: 12 min

Spanish (Español) translation by Luis Chiabrera (you can also view the original English article)

En este artículo, vamos a explorar cómo puede configurar un servidor OAuth2 completamente desarrollado en Laravel utilizando la biblioteca Laravel Passport. Revisaremos las configuraciones de servidor necesarias junto con un ejemplo del mundo real para demostrar cómo puede consumir las API de OAuth2.

Supongo que está familiarizado con los conceptos básicos de OAuth2 y el flujo, ya que los discutiremos en el contexto de Laravel. De hecho, la biblioteca Laravel Passport hace que sea muy fácil configurar rápidamente un servidor OAuth2 en su aplicación. Por lo tanto, otras aplicaciones de terceros pueden consumir API proporcionadas por su aplicación.

En la primera mitad del artículo, instalaremos y configuraremos las bibliotecas necesarias, y la segunda parte explicará cómo configurar recursos de demostración en su aplicación y consumirlos desde aplicaciones de terceros.

Configuraciones del servidor

En esta sección, vamos a instalar las dependencias necesarias para que la biblioteca de Passport funcione con Laravel. Después de la instalación, hay un poco de configuración que tendremos que pasar para que Laravel pueda detectar la biblioteca de Passport.

Avancemos e instalemos la biblioteca de Passport usando composer

1
$composer require laravel/passport

Eso es más o menos en lo que se refiere a la instalación de la biblioteca Passport. Ahora asegurémonos de que Laravel lo sepa.

Al trabajar con Laravel, probablemente conozca el concepto de un proveedor de servicios que le permite configurar servicios en su aplicación. Por lo tanto, siempre que quiera habilitar un nuevo servicio en su aplicación Laravel, solo necesita agregar una entrada de proveedor de servicio asociado en config / app.php.

Si aún no conoce a los proveedores de servicios de Laravel, le recomiendo encarecidamente que se haga un favor y lea este artículo introductorio que explica los conceptos básicos de los proveedores de servicios en Laravel.

En nuestro caso, solo tenemos que agregar el proveedor PassportServiceProvider a la lista de proveedores de servicios en config / app.php como se muestra en el siguiente fragmento.

1
...
2
...
3
'providers' => [
4
5
        /*

6
         * Laravel Framework Service Providers...

7
         */
8
        Illuminate\Auth\AuthServiceProvider::class,
9
        Illuminate\Broadcasting\BroadcastServiceProvider::class,
10
        Illuminate\Bus\BusServiceProvider::class,
11
        Illuminate\Cache\CacheServiceProvider::class,
12
        Illuminate\Foundation\Providers\ConsoleSupportServiceProvider::class,
13
        Illuminate\Cookie\CookieServiceProvider::class,
14
        Illuminate\Database\DatabaseServiceProvider::class,
15
        Illuminate\Encryption\EncryptionServiceProvider::class,
16
        Illuminate\Filesystem\FilesystemServiceProvider::class,
17
        Illuminate\Foundation\Providers\FoundationServiceProvider::class,
18
        Illuminate\Hashing\HashServiceProvider::class,
19
        Illuminate\Mail\MailServiceProvider::class,
20
        Illuminate\Notifications\NotificationServiceProvider::class,
21
        Illuminate\Pagination\PaginationServiceProvider::class,
22
        Illuminate\Pipeline\PipelineServiceProvider::class,
23
        Illuminate\Queue\QueueServiceProvider::class,
24
        Illuminate\Redis\RedisServiceProvider::class,
25
        Illuminate\Auth\Passwords\PasswordResetServiceProvider::class,
26
        Illuminate\Session\SessionServiceProvider::class,
27
        Illuminate\Translation\TranslationServiceProvider::class,
28
        Illuminate\Validation\ValidationServiceProvider::class,
29
        Illuminate\View\ViewServiceProvider::class,
30
31
        /*

32
         * Package Service Providers...

33
         */
34
        Laravel\Tinker\TinkerServiceProvider::class,
35
36
        /*

37
         * Application Service Providers...

38
         */
39
        App\Providers\AppServiceProvider::class,
40
        App\Providers\AuthServiceProvider::class,
41
        App\Providers\BroadcastServiceProvider::class,
42
        App\Providers\EventServiceProvider::class,
43
        App\Providers\RouteServiceProvider::class,
44
        Laravel\Passport\PassportServiceProvider::class,
45
],
46
...
47
...

A continuación, debemos ejecutar el comando migrate artesanal, que crea las tablas necesarias en una base de datos para la biblioteca Passport.

1
$php artisan migrate

Para ser precisos, crea siguiendo las tablas en la base de datos.

1
oauth_access_tokens
2
oauth_auth_codes
3
oauth_clients
4
oauth_personal_access_clients
5
oauth_refresh_tokens

A continuación, necesitamos generar un par de claves públicas y privadas que la biblioteca de Passport utilizará para el cifrado. Como era de esperar, la biblioteca Passport proporciona un comando artesanal para crearlo fácilmente.

1
$php artisan passport:install

Eso debería haber creado las claves en storage / oauth-public.key y storage / oauth-private.key. También crea algunas credenciales de demostración de cliente que veremos más adelante.

Avanzando, vamos a oauthificar la clase de modelo de usuario existente que Laravel usa para la autenticación. Para hacer eso, necesitamos agregar el rasgo HasApiTokens a la clase de modelo de User. Hagamos eso como se muestra en el siguiente fragmento.

1
<?php
2
3
namespace App;
4
5
use Illuminate\Notifications\Notifiable;
6
use Illuminate\Foundation\Auth\User as Authenticatable;
7
use Laravel\Passport\HasApiTokens;
8
9
class User extends Authenticatable
10
{
11
    use HasApiTokens;
12
13
    /**

14
     * The attributes that are mass assignable.

15
     *

16
     * @var array

17
     */
18
    protected $fillable = [
19
        'name', 'email', 'password',
20
    ];
21
22
    /**

23
     * The attributes that should be hidden for arrays.

24
     *

25
     * @var array

26
     */
27
    protected $hidden = [
28
        'password', 'remember_token',
29
    ];
30
}

El rasgo HasApiTokens contiene métodos auxiliares que se utilizan para validar los tokens en la solicitud y verificar el alcance de los recursos solicitados en el contexto del usuario autenticado actualmente.

Además, tenemos que registrar las rutas provistas por la biblioteca Passport con nuestra aplicación Laravel. Estas rutas se usarán para operaciones estándar de OAuth2, como autorización, solicitud de tokens de acceso y similares.

En el método de arranque de la app / Providers / AuthServiceProvider.php, registremos las rutas de la biblioteca de Passport.

1
...
2
...
3
/**

4
  * Register any authentication / authorization services.

5
  *

6
  * @return void

7
  */
8
public function boot()
9
{
10
    $this->registerPolicies();
11
    
12
    Passport::routes();
13
}
14
...
15
...

Por último, pero no por ello menos importante, debemos cambiar el controlador de la API de token a pasaporte en el archivo config / auth.php, ya que vamos a utilizar la biblioteca de Passport para la autenticación API.

1
'guards' => [
2
    'web' => [
3
        'driver' => 'session',
4
        'provider' => 'users',
5
    ],
6
7
    'api' => [
8
        'driver' => 'passport',
9
        'provider' => 'users',
10
    ],
11
],

Hasta ahora, hemos hecho todo lo que se requiere en lo que respecta a la configuración del servidor OAuth2.

Configure los recursos de demostración

En la sección anterior, hicimos todo el trabajo para configurar el servidor de autenticación OAuth2 en nuestra aplicación. En esta sección, configuraremos un recurso de demostración que podría solicitarse sobre la llamada API.

Intentaremos mantener las cosas simples. Nuestro recurso de demostración devuelve la información del usuario siempre que haya un parámetro de uid válido presente en la solicitud GET.

Vamos a crear un archivo de controlador app / Http / Controllers / UserController.php con los siguientes contenidos.

1
<?php
2
namespace App\Http\Controllers;
3
4
use App\Http\Controllers\Controller;
5
use Illuminate\Http\Request;
6
use App\User;
7
8
class UserController extends Controller
9
{
10
    public function get(Request $request)
11
    {
12
      $user_id = $request->get("uid", 0);
13
      $user = User::find($user_id);
14
      return $user;
15
    }
16
}

Como es habitual, también debe agregar una ruta asociada, que debe agregar en el archivo routes / web.php. Pero de lo que estamos hablando es de la ruta API, y por lo tanto, necesita un tratamiento especial.

Las rutas API se definen en el archivo routes / api.php. Entonces, continuemos y agreguemos nuestra ruta API personalizada como se muestra en el siguiente fragmento.

1
<?php
2
3
use Illuminate\Http\Request;
4
5
/*

6
|--------------------------------------------------------------------------

7
| API Routes

8
|--------------------------------------------------------------------------

9
|

10
| Here is where you can register API routes for your application. These

11
| routes are loaded by the RouteServiceProvider within a group which

12
| is assigned the "api" middleware group. Enjoy building your API!

13
|

14
*/
15
16
Route::middleware('auth:api')->get('/user', function (Request $request) {
17
    return $request->user();
18
});
19
20
// custom API route

21
Route::middleware('auth:api')->get('/user/get', 'UserController@get');

Aunque lo hemos definido como / user / get, la ruta API efectiva es / api / user / get, y eso es lo que debe usar cuando solicita un recurso sobre esa ruta. El prefijo api es manejado automáticamente por Laravel, ¡y no tienes que preocuparte por eso!

En la siguiente y última sección, analizaremos cómo puede crear credenciales de clientes y consumir la API de OAuth2.

Cómo consumir las API de OAuth2

Ahora que hemos configurado el servidor OAuth2 en nuestra aplicación, cualquier tercero puede conectarse a nuestro servidor con OAuth y consumir las API disponibles en nuestra aplicación.

En primer lugar, las aplicaciones de terceros deben registrarse en nuestra aplicación para poder consumir API. En otras palabras, se consideran aplicaciones cliente y recibirán una identificación de cliente y un secreto de cliente al registrarse.

La biblioteca Passport proporciona un comando artesanal para crear cuentas de clientes sin mucha molestia. Avancemos y creemos una cuenta de cliente demo.

1
$php artisan passport:client
2
Which user ID should the client be assigned to?:
3
 > 1
4
5
 What should we name the client?:
6
 > Demo OAuth2 Client Account
7
8
 Where should we redirect the request after authorization? [https://localhost/auth/callback]:
9
 > http://localhost/oauth2_client/callback.php
10
11
New client created successfully.
12
Client ID: 1
13
Client secret: zMm0tQ9Cp7LbjK3QTgPy1pssoT1X0u7sg0YWUW01

Cuando ejecuta el comando passport:client artesanal: , le hace algunas preguntas antes de crear la cuenta del cliente. De ellos, hay uno importante que le pide la callback URL

La callback URL es aquella en la que los usuarios serán redirigidos al extremo de terceros después de la autorización. Y ahí es donde se enviará el código de autorización que se supone que se usará a cambio del token de acceso. Estamos a punto de crear ese archivo en un momento.

Ahora, estamos listos para probar las API de OAuth2 en la aplicación Laravel.

Para fines de demostración, crearé el directorio oauth2_client debajo de la raíz del documento en primer lugar. Idealmente, estos archivos se ubicarán en el extremo de terceros que desea consumir API en nuestra aplicación Laravel.

Vamos a crear el archivo oauth2_client / auth_redirection.php con los siguientes contenidos.

1
<?php
2
$query = http_build_query(array(
3
    'client_id' => '1',
4
    'redirect_uri' => 'http://localhost/oauth2_client/callback.php',
5
    'response_type' => 'code',
6
    'scope' => '',
7
));
8
9
header('Location: http://your-laravel-site-url/oauth/authorize?'.$query);

Asegúrese de cambiar los parámetros client_id y redirect_uri para que reflejen su propia configuración, las que utilizó al crear la cuenta del cliente de demostración.

A continuación, creemos el archivo oauth2_client / callback.php con los siguientes contenidos.

1
<?php
2
// check if the response includes authorization_code

3
if (isset($_REQUEST['code']) && $_REQUEST['code'])
4
{
5
    $ch = curl_init();
6
    $url = 'http://your-laravel-site-url/oauth/token';
7
8
    $params = array(
9
        'grant_type' => 'authorization_code',
10
        'client_id' => '1',
11
        'client_secret' => 'zMm0tQ9Cp7LbjK3QTgPy1pssoT1X0u7sg0YWUW01',
12
        'redirect_uri' => 'http://localhost/oauth2_client/callback.php',
13
        'code' => $_REQUEST['code']
14
    );
15
16
    curl_setopt($ch,CURLOPT_URL, $url);
17
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
18
19
    $params_string = '';
20
21
    if (is_array($params) && count($params))
22
    {
23
        foreach($params as $key=>$value) {
24
            $params_string .= $key.'='.$value.'&';
25
        }
26
27
        rtrim($params_string, '&');
28
29
        curl_setopt($ch,CURLOPT_POST, count($params));
30
        curl_setopt($ch,CURLOPT_POSTFIELDS, $params_string);
31
    }
32
33
    $result = curl_exec($ch);
34
    curl_close($ch);
35
    $response = json_decode($result);
36
    
37
    // check if the response includes access_token

38
    if (isset($response->access_token) && $response->access_token)
39
    {
40
        // you would like to store the access_token in the session though...

41
        $access_token = $response->access_token;
42
43
        // use above token to make further api calls in this session or until the access token expires

44
        $ch = curl_init();
45
        $url = 'http://your-laravel-site-url/api/user/get';
46
        $header = array(
47
        'Authorization: Bearer '. $access_token
48
        );
49
        $query = http_build_query(array('uid' => '1'));
50
51
        curl_setopt($ch,CURLOPT_URL, $url . '?' . $query);
52
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
53
        curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
54
        $result = curl_exec($ch);
55
        curl_close($ch);
56
        $response = json_decode($result);
57
        var_dump($result);
58
    }
59
    else
60
    {
61
        // for some reason, the access_token was not available

62
        // debugging goes here

63
    }
64
}

De nuevo, asegúrese de ajustar las URL y las credenciales del cliente de acuerdo con su configuración en el archivo anterior.

Cómo funciona en conjunto

En esta sección, lo probaremos por completo desde la perspectiva de un usuario final. Como usuario final, hay dos aplicaciones frente a usted:

  1. El primero es la aplicación Laravel con la que ya tiene una cuenta. Contiene su información que podría compartir con otras aplicaciones de terceros.
  2. El segundo es la aplicación cliente de demostración demo, auth_redirection.php y callback.php, que quiere obtener su información de la aplicación Laravel utilizando la API OAuth.

El flujo comienza desde la aplicación cliente de terceros. Continúa y abre la URL http: //localhost/oauth2_client/auth_redirection.php en tu navegador, y eso debería redireccionarte a la aplicación Laravel. Si aún no ha iniciado sesión en la aplicación Laravel, la aplicación le pedirá que lo haga en primer lugar.

Una vez que el usuario inicia sesión, la aplicación muestra la página de autorización.

Si el usuario autoriza esa solicitud, el usuario será redirigido a la aplicación de cliente de terceros en http: //localhost/oauth2_client/callback.php junto con el code como el parámetro GET que contiene el código de autorización.

Una vez que la aplicación de terceros recibe el código de autorización, puede intercambiar ese código con la aplicación Laravel para obtener el token de acceso. Y eso es exactamente lo que ha hecho en el siguiente fragmento del archivo oauth2_client / callback.php.

1
$ch = curl_init();
2
$url = 'http://your-laravel-site-url/oauth/token';
3
4
$params = array(
5
    'grant_type' => 'authorization_code',
6
    'client_id' => '1',
7
    'client_secret' => 'zMm0tQ9Cp7LbjK3QTgPy1pssoT1X0u7sg0YWUW01',
8
    'redirect_uri' => 'http://localhost/oauth2_client/callback.php',
9
    'code' => $_REQUEST['code']
10
);
11
12
curl_setopt($ch,CURLOPT_URL, $url);
13
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
14
15
$params_string = '';
16
17
if (is_array($params) && count($params))
18
{
19
    foreach($params as $key=>$value) {
20
        $params_string .= $key.'='.$value.'&';
21
    }
22
23
    rtrim($params_string, '&');
24
25
    curl_setopt($ch,CURLOPT_POST, count($params));
26
    curl_setopt($ch,CURLOPT_POSTFIELDS, $params_string);
27
}
28
29
$result = curl_exec($ch);
30
curl_close($ch);
31
$response = json_decode($result);

A continuación, la aplicación de terceros comprueba la respuesta de la solicitud CURL para ver si contiene un token de acceso válido en primer lugar.

Tan pronto como la aplicación de terceros obtenga el token de acceso, podría usar ese token para realizar más llamadas a la API para solicitar recursos según sea necesario desde la aplicación Laravel. Por supuesto, el token de acceso debe pasarse en cada solicitud que solicite recursos de la aplicación Laravel.

Hemos tratado de imitar el caso de uso en el sentido de que la aplicación de terceros quiere acceder a la información del usuario desde la aplicación Laravel. Y ya hemos creado un punto final API, http: // su-laravel-site-url / api / user / get, en la aplicación Laravel que lo facilita.

1
// check if the response includes access_token

2
if (isset($response->access_token) && $response->access_token)
3
{
4
    // you would like to store the access_token in the session though...

5
    $access_token = $response->access_token;
6
7
    // use above token to make further api calls in this session or until the access token expires

8
    $ch = curl_init();
9
    $url = 'http://your-laravel-site-url/api/user/get';
10
    $header = array(
11
    'Authorization: Bearer '. $access_token
12
    );
13
    $query = http_build_query(array('uid' => '1'));
14
15
    curl_setopt($ch,CURLOPT_URL, $url . '?' . $query);
16
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
17
    curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
18
    $result = curl_exec($ch);
19
    curl_close($ch);
20
    $response = json_decode($result);
21
    var_dump($result);
22
}

Así que ese es el flujo completo de cómo se supone que debes consumir las API de OAuth2 en Laravel.

Y con eso, hemos llegado al final de este artículo.

Conclusión

Hoy exploramos la biblioteca de Passport en Laravel, lo que nos permite configurar un servidor OAuth2 en una aplicación muy fácilmente.

Para aquellos de ustedes que recién están empezando con Laravel o buscando ampliar su conocimiento, sitio o aplicación con extensiones, tenemos una variedad de cosas que pueden estudiar en Envato Market.

¡No dude en compartir sus pensamientos y consultas utilizando el feed a continuación!

Advertisement
Did you find this post useful?
Want a weekly email summary?
Subscribe below and we’ll send you a weekly email summary of all new Code tutorials. Never miss out on learning about the next big thing.
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.