# Authenticate users with Guardian
# Objective
In this example, we will implement the user authentication in Laravel using Guardian.
The key-actions are the following:
- The user sends its credentials in a POST request.
- The controller validates its credentials.
- The controller generates the payload to sign.
- Guardian sign the payload by generating a token for the user.
- The token is sent back to the user.
- If the credentials are invalid, the controller sends an error to the user.
# Implementation
# Configuration
In this example, we will use a "login"
ECDSA key, configured with the ES512
algorithm and the P-521
curve.
This is a quite good compromise between security and speed.
See the configuration documentation for the list of all available cryptographic algorithms.
# config/guardian.php
In the config/guardian.php
file, add the following configuration:
// config/guardian.php
return [
'defaults' => [
'authority' => 'login',
],
'authorities' => [
// your other authorities definitions
'login' => [
'key' => 'login',
'claims' => 'login'
]
],
'keys' => [
// your other keys definitions
'login' => [
'algorithm' => 'ES512',
'curve' => 'P-521',
'path' => storage_path('login.json'),
]
],
'claims' => [
// your others claims definitions
'login' => [
'iss' => 'My application',
'aud' => 'My audience',
'exp' => '+15 days',
'iat' => 'now',
'nbf' => 'now',
'jid' => 'uuid',
]
]
];
# config/auth.php
// config/auth.php
return [
'guards' => [
'guardian' => [
'driver' => 'guardian',
'provider' => 'eloquent',
'authority' => 'login',
]
]
];
# Controller action
In the controller of your choice, create a new action.
In this example, we will use a dummy AuthController
, located in app/Http/Controllers
directory.
<?php
declare(strict_types=1);
namespace App\Http\Controllers;
use Illuminate\Auth\AuthenticationException;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Windy\Guardian\Guardian;
class AuthController
{
/**
* @param Request $request The Illuminate HTTP request.
*
* @return string[] The token.
*
* @throws AuthenticationException
*/
public function login(Request $request): array
{
if (!Auth::attempt($request->only('email', 'password'))) {
throw new AuthenticationException();
}
/** @var string $token The serialized JWS. */
$token = Guardian::sign(Auth::user());
// $token = Guardian::get('login')->sign(Auth::user()); // use a non-default authority
return ['token' => $token];
}
}
Using the Guardian
facade, we can sign a token for the given user.
# Register the route
To finish, we simply have to register our route with something like:
# Laravel
// routes/api.php
Route::post('/login', App\Http\Controllers\AuthController::class . '@login');
# Lumen
// routes/web.php
$router->post('/login', App\Http\Controllers\AuthController::class . '@login');
# Test the login chain
Send a post request to the route with the user credentials:
# For example, using curl
curl -X POST -d email=mathieu@mathrix.fr&password=123456
The expected JSON response is the following:
{
"token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiJ9.eyJzdWIiOiIxIiwiaXNzIjoiWW91ciBJc3N1ZXIiLCJhdWQiOiJZb3VyIEF1ZGllbmNlIiwiZXhwIjoxNTk1NTU5NTY1LCJuYmYiOjE1ODc2OTcxNjUsImlhdCI6MTU4NzY5NzE2NSwiamlkIjoiZmU0ZDhlNDctZjRiMi00NDE5LWFhOTUtODFlNDMxNzFlNzA0In0.9LZgKaOwZpj3OKbpLb-cuE0AurZb2lO7ekN7eAGKi4_aKE1LxvJhCVkwFsfKkjqTwVkPshyHjTLAeYl03qGrFQ"
}
You can debug this token on jwt.io (opens new window).