Introduction to Laravel 7 Sanctum (formerly Airlock)

As the Laravel ecosystem evolves, it’s continuously adding new and useful tools, features. One of those new features is Sanctum. Sanctum was formerly named Airlock.

If you remember Laravel Passport, you’ll enjoy the new Laravel Sanctum feature! Sanctum was designed to provide an ultra-lightweight authentication system for your single-page applications, mobile applications and simple token-based API authentications.

I’ve been using Sanctum on two different Laravel-based applications and I’m in love with it. One of the features I love is the ability to generate multiple tokens (“API Tokens”) per user account with their own scopes and abilities with simple method calls.

It may not seem like a very useful feature at first, but let’s put this into perspective. Let’s say you’re designing a Billing system in Laravel, and you want to provide mobile applications an API to access billing information. Now, traditionally you would have to manually create the entire API system or leverage a third-party API module to do it. Then have to account for every possible entry point, data access rights for your account, and more variables that are necessary for controlling the access securely.

That’s a lot of work, especially for a small organization. Airlock tries to unravel some of that, now your application can simply integrate API Tokens with Airlock, and pin the proper user account through tokens being the authentication system. Then, a good chunk of the work needed to authenticate and properly pin the user to their own account is done. Within your Laravel code you can keep using the existing authentication checking mechanisms without any issue given that any “third-party” authentication will originate from Airlock.

Getting Started with Sanctum

Like many other Laravel official packages, you’ll need composer to install this one. Here’s the command you’ll want to run:

composer require laravel/sanctum

This will download all the assets required for Sanctum, but you’re not ready to use Sanctum just yet. You will need to publish the Sanctum configuration and database migration files before you can use it and run artisan migrate for the database changes, you can do that by running:

php artisan vendor:publish —provider=“Laravel\Sanctum\SanctumServiceProvider”
php artisan migrate

Once you’ve done those commands, Laravel Sanctum is ready to be leveraged.

In this introductory post, We’re going to be utilizing API Authentication, so open up app/Http/Kernel.php and add the following content:

use Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful;

// middleware: api ……
‘api’ => [
    EnsureFrontendRequestsAreStateful::class,
    ‘throttle:60,1’,
    \Illuminate\Routing\Middleware\SubstituteBindings::class
]

Issuing API Tokens

We’ll start by issuing user tokens. In order to do this, we need to open up our User model file (app/User.php in standard installations), and add the following to the file:

use Laravel\Sanctum\HasApiTokens;

class User extends Authenticable {
    use HasApiTokens, Notifiable;
}

Next, we want to issue a token for this user, so create a route endpoint of /Account/Tokens/request. Next, in the request endpoInt of your controller add the logic necessary to render a token with specific abilities to access their account. Here’s how that looks:

public function requestToken( Request $request ) {
  $scope = array(‘account:read’, ‘billing:read’, ‘account:support:openticket’, ‘account:support:readticket’);

  $user = Auth::user();

  $token = $user->createToken(‘account_auth_token’, $scope)->plainTextToken;

  return view(‘authenticated.account.tokens.request’, [‘token’ => $token]);
}

Now, the logic above for requesting tokens will generate one named “account_auth_token”, add the scopes we’ve set and push it into the database.

Revoking API Tokens

In order to revoke API tokens, it’s as simple as granting them. Here’s how to revoke a specific token, versus all tokens:

// Revoke **ALL** Tokens
$user->tokens()->delete();
// Revoke specific token by ID
$user->tokens()->where(‘id’, $TOKEN_ID)->delete(); // this is an Eloquent model provided by tokens() function.

Often times you won’t have the token ID available when going to revoke, so you’ll need to know which token to revoke first. You can iterate on them like so, and decide on which to revoke:

foreach($user->tokens as $token) {
  // meta object $token contains information, like ORM result
}

Checking Token Permissions

We’ve created the previous token of billing_auth_token, let’s say one of your protected endpoints want to check the ability of said token to perform an action (eg. Open Ticket), in order to do this first ensure that your controller checks the user object with the tokenCan function, here’s how that looks:

public function apiCreateTicket() {
    $user = Auth::user();
    if(!$user->tokenCan(‘account:support:openticket’)) {
        abort(403);
    }
}

The code above has checked if the user doesn’t have the account:support:openticket scope, and if not, aborts the request with a 403 Forbidden. You’ll want to add this to any API functionality that checks scope, or if you’d like to get fancy add additional middleware for route groups.

Protecting API Routes

Since we’re using the API functionality, in our routes/api.php, let’s go ahead and add the airlock middleware to the system.

Route::middleware(‘auth:airlock’)->get(‘/api/v4/account/support/tickets/open’, ’ApiSupportController@apiCreateTicket’);

The middleware will handle the initial authentication to ensure your request is signed and validated, then it’s up to you to check the token permissions.

Testing Airlock

Now, we’ll want to test our Sanctum installation and ensure our new route scope is working as intended. Thankfully, Laravel has built-in actingAs functionality that’ll let us authenticate. Here’s how that test would look:

use App\User;
use Laravel\Sanctum\Sanctum;

public function test_support_can_open_ticket() {
    Sanctum::actingAs( factory(User::class)->create(), [‘account:support:openticket’]);

    $response = $this->get(‘/api/v4/account/support/tickets/open’);

    $response->assertOk();
}

That’ll let you test the routes and ensure the assertions of token grants are working as you expect.

Considerations

As I come to an end of the introduction post in this series, it’s important to take a few considerations at hand:

  1. Always ensure your grant assertions are correct (test, test, test)
  2. Make sure to call tokenCan or write middleware to check token grants prior to controller function being executed
  3. Make error responses clear and concise. In my example I simply 403 the request, however, you may want to send back error payload in JSON if you’re providing third-party access.
  4. Check out the Laravel Documentation for more information on Sanctum.

I hope you’ve enjoyed this introduction post! If you’d like to see a full series on building MVC applications with Sanctum, let me know!