Laravel API Authentication using Sanctum Package
In this tutorial, we will look at the Laravel sanctum package. We will discuss how it can be used to authenticate Single Page Applications (SPA) or even token-based APIs. <!--more--> We will create a simple Laravel project, issue users with API tokens, and authenticate the application using the Laravel inbuilt session.
The article will also highlight the advantages of the Sanctum package over Laravel passport.
Table of contents
Prerequisites
- Basic knowledge of Laravel.
- You'll need to have API test tools such as Postman installed.
Objective
By the end of this tutorial, you should be able to authenticate your user's API calls and Single Page Applications (SPA) using Laravel Sanctum.
Project setup
Let's set up a Laravel project and install the Sanctum package.
laravel new sanctumApp
The command above generates your Laravel project skeleton. This may take a while depending on your internet connection.
Next, cd
into your project root and run the following command:
cd sanctumApp
composer require laravel/sanctum
Output:
- Installing laravel/sanctum (v2.11.2): Downloading (100%)
.................
Discovered Package: fruitcake/laravel-cors
Discovered Package: laravel/sail
Discovered Package: laravel/sanctum
Discovered Package: laravel/tinker
....................
Now that we've installed sanctum
, we need to configure and migrate files by running the following command:
php artisan vendor:publish --provider="Laravel\Sanctum\SanctumServiceProvider"
Output:
Copied Directory [/vendor/laravel/sanctum/database/migrations] To [/database/migrations]
Copied File [/vendor/laravel/sanctum/config/sanctum.php] To [/config/sanctum.php]
Publishing complete.
With the sanctum files published, let's now set up our database by editing the .env
file contents as follows:
.............................
DB_CONNECTION = mysql #edit this connection depending on your connection
DB_HOST = 127.0.0.1 #edit this to meet your requirements
DB_PORT = 3306
DB_DATABASE = sanctum #this is generated by default
DB_USERNAME = EnterYourDBUsername
DB_PASSWORD = EnterYourDBPassoword
..........................
Now let's proceed and create our database on a MySQL server
by running the following command in the command line:
mysql -u root -p
Output:
.................
Enter password:
.....................
mysql>
In front of mysql>
, run the SQL commmand below to create a sanctum
database:
mysql> CREATE DATABASE sanctum;
Output:
Query OK, 1 row affected (0.06 sec)
Let's now proceed to migrate our application as shown below:
php artisan migrate
Output:
Migration table created successfully.
.........................................
Migrating: 2019_12_14_000001_create_personal_access_tokens_table
Migrated: 2019_12_14_000001_create_personal_access_tokens_table (203.38ms)
You will notice that the personal_tokens
table is generated. This is important to note because we'll need it later on in the article.
With our database setup, one last step we'll need is to notify the User
model about this package.
Let's see how this is done:
<?php
..........................................
use Laravel\Sanctum\HasApiTokens;
class User extends Authenticatable
{
....................
use HasApiTokens;
..............................
protected $fillable = [
'name',
'email',
'password',
];
.............................
}
In the above User
model, we have imported the HasApiTokens
trait from Laravel\Sanctum\HasApiTokens
. This trait exposes the create token()
method that we will use to issue tokens.
Route authentications
Routing is one of the core features of a Laravel application. In this part, we will set up our api
routes in the routes/api.php
file as follows:
<?php
...............
//import controller
use App\Http\Controllers\AuthenticationController;
................
//register new user
Route::post('/create-account', [AuthenticationController::class, 'createAccount']);
//login user
Route::post('/signin', [AuthenticationController::class, 'signin']);
//using middleware
Route::group(['middleware' => ['auth:sanctum']], function () {
Route::get('/profile', function(Request $request) {
return auth()->user();
});
Route::post('/sign-out', [AuthenticationController::class, 'logout']);
});
In the script above, we define four routes. The first is a POST
request to register
a new user using the AuthenticationController.createAccount()
method.
We have also defined other routes, to log in
, view user profile
, and logout
users.
You may have noticed that we also used the AuthenticationController
while it had not been created.
Let's go ahead and create this controller by running the command below:
php artisan make:controller AuthenticationController
Now proceed and edit this controller as follows:
<?php
..............................................
class AuthenticationController extends Controller
{
//this method adds new users
public function createAccount(Request $request)
{
$attr = $request->validate([
'name' => 'required|string|max:255',
'email' => 'required|string|email|unique:users,email',
'password' => 'required|string|min:6|confirmed'
]);
$user = User::create([
'name' => $attr['name'],
'password' => bcrypt($attr['password']),
'email' => $attr['email']
]);
return $this->success([
'token' => $user->createToken('tokens')->plainTextToken
]);
}
//use this method to signin users
public function signin(Request $request)
{
$attr = $request->validate([
'email' => 'required|string|email|',
'password' => 'required|string|min:6'
]);
if (!Auth::attempt($attr)) {
return $this->error('Credentials not match', 401);
}
return $this->success([
'token' => auth()->user()->createToken('API Token')->plainTextToken
]);
}
// this method signs out users by removing tokens
public function signout()
{
auth()->user()->tokens()->delete();
return [
'message' => 'Tokens Revoked'
];
}
}
We have a simple logic in the Controller above. The createAccount()
method creates new validated users. It then generates tokens if registered successfully.
The signin()
function authenticates users and generates access tokens
on successful login. Finally, the signout()
method removes the user's session.
Now test your application on Postman. Depending on the routes you have used, you should be able to see the following output:
Registration output:
Conclusion
In this tutorial, we looked at what Laravel Sanctum is and what it does. We also looked at how it is different from Laravel Passport and when to use it.
Finally, we covered how to use Laravel Sanctum to authenticate and give access to users. You can, therefore, use this knowledge to build powerful APIs.
Happy coding!
Peer Review Contributions by: Odhiambo Paul