OAuth 2

Mejor sistema para la validación de peticiones para acceder a recursos de nuestra API.. En el caso de las APIs, al ser stateless, no hay manera de mantener sesiones de los usuarios o validar sus credenciales.

Para esto existe OAuth que es un sistema que permite, no solo validar que quien haga la petición sea un usuario sino que para clientes externos exista la manera de que consuman la API como si fueran usuarios.

Existen diferentes maneras en que funciona OAuth, entre ellos el Authorization token,

https://www.digitalocean.com/community/tutorials/an-introduction-to-oauth-2

https://solidgeargroup.com/oauth2-protocolo-de-autorizacion?lang=es

Laravel Passport - API Authentication

Dependencia propia de Laravel que permite fácilmente realizar autenticación por medio de OAuth 2.

  • Descargar paquete

composer require laravel/passport
  • Registrar el service provider en config/app.php

Laravel\Passport\PassportServiceProvider::class,

Nota: Desde Laravel 5.5 no es necesario registrar el service provider

  • Correr migraciones de Passport

php artisan migrate

If you are not going to use Passport's default migrations, you should call the Passport::ignoreMigrations method in the register method of your AppServiceProvider. You may export the default migrations using php artisan vendor:publish --tag=passport-migrations.

Para mongodb, personalizar migraciones usando Jenseggers Schema

use Jenssegers\Mongodb\Schema;

Schema::create('password_resets', function ($collection) {
    $collection->string('email')->index();
    $collection->string('token');
    $collection->timestamp('created_at')->nullable();
});

Correr migraciones

MongoDB shell version: 3.2.17
connecting to: test
> use aquapp2
switched to db aquapp2
> show collections
migrations
node_types
nodes
oauth_access_tokens
oauth_auth_codes
oauth_clients
oauth_personal_access_clients
oauth_refresh_tokens
password_resets
sensor_data
users
  • Instalar Passport:

Generar llaves necesarias para asegurar los tokens y creación de clientes. Ejecuta ambos comandos passport:keys y passport:client

php artisan passport:install

Encryption keys generated successfully.

Personal access client created successfully.
Client ID: 1
Client Secret: 4EKYJLAVZzL3ONmfLQB2GQXNzihGl8mEsN7FTGnU
Password grant client created successfully.
Client ID: 2
Client Secret: FTIaurEONfBEx45rto61ckFnV5RGvJZWqXPVm7tG

Nota: Las llaves creadas se encuentran en la carpeta storage, con los nombres oauth-private.key y oauth-public.key. Estas llaves deben ser ocultas y únicas, diferentes para el env de desarrollo y el de producción, importante ignorarlas

.gitignore

/storage/*.key

Los desarrolladores de apps que necesiten interactuar con nuestra API deberán registrar su app en la nuestra creando un cliente. Este proceso consiste en proveer el nombre de su app y la URL a la cuál se redirigirá luego de que los usuarios aprueben su solicitud de autorización.

Se generan dos tipos de clientes:

  • Personal access client: permite generar access token personales para los usuarios de la API.

  • Password grant client: permite generar access tokens de tipo password para los usuarios de la API.

Autenticar usuarios usando access tokens

  • Usar trait HasApiTokens en modelo User

Añadir el trait Laravel\Passport\HasApiTokens al modelo App\User, este le permitirá al modelo inspeccionar el token y los alcances del usuario autenticado

use Laravel\Passport\HasApiTokens;

class User extends Authenticatable
{
    use Notifiable, HasApiTokens, SoftDeletes;
    ...
}

Usando el trait se puede acceder a varias funciones, entre ellas

public function clients()
{
    return $this->hasMany(Client::class, 'user_id');
}

/**
 * Get all of the access tokens for the user.
 *
 * @return \Illuminate\Database\Eloquent\Collection
 */
public function tokens()
{
    return $this->hasMany(Token::class, 'user_id')->orderBy('created_at', 'desc');
}

Estas relaciones indican que:

  • Un usuario tiene muchos clientes

  • Un usuario puede tener muchos tokens

Además se cuenta con un método para generar token para el usuario etc.

  • Registrar rutas

En Providers/AuthServiceProviders.php, en método boot

use Laravel\Passport\Passport;

public function boot()
{
    $this->registerPolicies();

    Passport::routes();
}

Dentro de las rutas de oauth se encuentra

POST |oauth/token|
\Laravel\Passport\Http\Controllers\AccessTokenController@issueToken| throttle

esta, tiene como middleware throttle, vamos a crear nuestra propia versión con el middeware api

  • Configurar sistema de autenticación

En config/auth.php definir como driver del guard api a passport

'guards' => [
    ...

    'api' => [
        'driver' => 'passport',
        ...
    ],
],

así cuando se tengan peticiones a la api, y estas estén protegidas con el middleware auth, passport se encargará de verificar el access token

  • Definir tiempo de expiración de los tokens

Usando método tokensExpireIn

use Carbon\Carbon;

public function boot()
{
    $this->registerPolicies();

    Passport::routes();

    Passport::tokensExpireIn(Carbon::now()->addMinutes(30)); // valid 30 minutos

    Passport::refreshTokensExpireIn(Carbon::now()->addDays(30)); 
}

tokensExpireIn: una vez generado un token, este será válido únicamente por 30 minutos

refreshTokensExpireIn: se puede solicitar un refresh token a más tardar 30 días después de haber sido generado por primera vez. Luego de vencido ese plazo, tendría que realizar nuevamente el flujo de autorización para obtener un nuevo token.

Last updated

Was this helpful?