Courses

How to Build Laravel 12 API From Scratch

Authentication with Laravel Sanctum and API Tokens

Summary of this lesson:
- Personal access tokens implementation
- Creating and managing API tokens
- Adding token abilities (permissions)

This lesson will look at Laravel API authentication with Laravel Sanctum and API tokens. To understand how it is used and in what situations, you should read the official documentation.

From the docs:

This feature is inspired by GitHub and other applications which issue "personal access tokens".

Every user of your system would have a personal access token, which they would pass when making API calls.


After creating a new Laravel project and running the migrations, we have a personal_access_tokens table.

Next, you need to create a token for the user in your application. It could be some action panel on your page, some action on login, or automatically done after registration.

But, to create a token, the HasApiTokens trait has to be added in a User Model. It should be done after the install:api artisan command was executed.

app/Models/User.php:

use Laravel\Sanctum\HasApiTokens;
 
class User extends Authenticatable
{
use HasApiTokens, HasFactory, Notifiable;
use HasApiTokens;
 
// ...
}

Next, you must protect API routes using the auth:sanctum Middleware. It's the same Middleware we used in the previous lesson for the SPA applications.

routes/api.php:

Route::get('/user', function (Request $request) {
return $request->user();
})->middleware('auth:sanctum');
 
Route::apiResource('categories', \App\Http\Controllers\Api\CategoryController::class)
->middleware('auth:sanctum');
 
Route::get('products', [\App\Http\Controllers\Api\ProductController::class, 'index']);

Now, if we try to access categories without passing any token, we will receive an Unauthenticated message with a 401 Unauthorized status code.

Let's try to create a token for a user using tinker.

If you don't have any users, create one.

Now, let's create a token by passing some name.

The token is in the plainTextToken, which needs to be passed for every API call. In the client, add the created token as a Bearer token. Now, we can see the list of the categories from the API.

In the database, we have an encoded token.

If you want to delete all the tokens, you can do that.


Finally, when using tokens, you can pass abilities, better known as permissions. When creating a token, the second parameter is the array of abilities.

Let's create a token that can view all categories but not a specific category.

In the Controller, we need to check if the user has access. The check is done on the authenticated user Model using the tokenCan method.

app/Http/Controllers/Api/CategoryController.php:

class CategoryController extends Controller
{
public function index()
{
abort_if(! auth()->user()->tokenCan('categories-list'), 403);
 
return CategoryResource::collection(Category::all());
}
 
public function show(Category $category)
{
abort_if(! auth()->user()->tokenCan('categories-show'), 403);
 
return new CategoryResource($category);
}
 
// ...
}

With the new token, we can see a list of the categories.

But, when we try to view a single existing category, we get a 403 forbidden status.

This token check can also be done using Middleware, Policies, or your other preferred way.

Previous: Authentication with Laravel Sanctum and SPA
avatar

Nit:

HasApiTokens is declared twice on the user model in the first code snippet.

👍 2
avatar
You can use Markdown
avatar

Hello just want to ask, upon using the laravel tinker and executing $user = User::first(); the output is null. Can you please direct me on the right direction to populate the right output as per 2nd screenshot?

avatar

Create user manually in the db first

avatar

well noted on that. thank you 😊

avatar

in tinker:

$user = App\Models\User::factory()->create()

$user->createToken('developer-access')

avatar
You can use Markdown
avatar

is there any example how to store and use the token with sacntum/passport API token....or i just have to make separate API for login and logout to use with mobile apps...and also refresh token.. i was thinking to use token for web and mobile

avatar
You can use Markdown
avatar
You can use Markdown