Reading Time: 7 minutes

Introduction

Laravel Sanctum authentication tutorial; In this tutorial, we will share how to create or build a secure PHP RESTful API in Laravel application with the help of the Laravel sanctum package. Likewise, we will explain to you step by step how to test the Laravel Sanctum authentication REST API using the Postman testing tool.

Laravel Sanctum provides a lightweight authentication system for SPAs (single-page applications), mobile apps, and simple token-based APIs. Sanctum allows users of your application to create multiple API tokens. These tokens can be granted capabilities / scopes that specify the actions they are allowed to perform.

So, let’s start creating the sanctum rest api in the laravel application without getting into theories.

Laravel 9 REST API with Sanctum Auth

Here are the instructions going toward building an uncomplicated, secure restful api in the laravel app.

  • Step 1: Create Laravel Project
  • Step 2: Configure Database
  • Step 3: Install Laravel Sanctum Pacakage
  • Step 4: Build API Resources
  • Step 5: Set Up Controllers
  • Step 6: Create REST API Routes
  • Step 7: Test REST API in Postman

Create Laravel Project

Before creating a Laravel project, ensure that your local machine has PHP and Composer installed. On macOS, PHP and Composer can be installed via Homebrew. In addition, installing Node and NPM is recommended.

You can check out the laravel docs on other methods to create a laravel project.

composer create-project --prefer-dist laravel/laravel laravel-sanctum-auth
Bash

Configure database in .env

You have to add the database details into the .env configuration file to communicate between the laravel and mysql database.

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=db_name
DB_USERNAME=root
DB_PASSWORD=password
.properties

Note – Append UNIX_SOCKET and DB_SOCKET variables if developing using MAMP on MacOs:

UNIX_SOCKET=/Applications/MAMP/tmp/mysql/mysql.sock
DB_SOCKET=/Applications/MAMP/tmp/mysql/mysql.sock
Bash

Install Laravel Sanctum Pacakage

Install Laravel Sanctum via the Composer package manager:

composer require laravel/sanctum
Bash

Next, proceed to publish the Sanctum configuration and migration files using the vendor:publish Artisan command. The sanctum configuration file will be placed in your application’s config directory:

php artisan vendor:publish --provider="Laravel\Sanctum\SanctumServiceProvider"
Bash

Next, proceed to include Sanctum’s middleware to your api middleware group within your application’s app/Http/Kernel.php file:

protected $middlewareGroups = [
...
...
    'api' => [
        \Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class,
        'throttle:api',
        \Illuminate\Routing\Middleware\SubstituteBindings::class,
    ],
...
...
];
PHP

Finally, run your database migrations. Sanctum will create one database table in which to store API tokens:

php artisan migrate
Bash
Add the sanctum HasApiTokens class into the app/Models/User.php file.
<?php
namespace App\Models;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
// sanctum
use Laravel\Sanctum\HasApiTokens;

class User extends Authenticatable
{
    use HasApiTokens, HasFactory, Notifiable;
    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $fillable = [
        'name',
        'email',
        'password',
    ];
    /**
     * The attributes that should be hidden for arrays.
     *
     * @var array
     */
    protected $hidden = [
        'password',
        'remember_token',
    ];
    /**
     * The attributes that should be cast to native types.
     *
     * @var array
     */
    protected $casts = [
        'email_verified_at' => 'datetime',
    ];
}
PHP

Create Product model and migration

Use php artisan command to create a new Product model and product migration table, the -m flag generates the migration for the model.

php artisan make:model Product -m
Bash
Terminal Output:
Model created successfully.
Created Migration: 2022_06_17_113117_create_products_table
Bash

You need to add a few properties into the migration file created, open and add code into the database/migrations/{timestamp}create_products_table.php file.

Note – The migrations are created prepended with a specific timestamp i.e 2022_06_17_113117_create_products_table.php in our case

<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateProductsTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('products', function (Blueprint $table) {
            $table->id();
            $table->string('name');
            $table->text('description');
            $table->timestamps();
        });
    }
    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('products');
    }
}
PHP

Next, add $fillable array properties for for the Product model in app/Models/Product.php file. This simply is defining which model attributes you want to make mass assignable. In our case its name and description.

<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Product extends Model
{
    use HasFactory;
    protected $fillable = [
        'name', 
        'description'
    ];    
}
PHP

Proceed to run the database migration:

php artisan migrate
Bash

Create API Resources

Laravel API Resources creates a transformation layer that sits between your Eloquent models and the JSON responses that are actually returned to your application’s users.

Execute command to generate Product eloquent api resources.

php artisan make:resource Product
Bash

Place the code below into the app/Http/Resources/Product.php
file:

<?php
  
namespace App\Http\Resources;
use Illuminate\Http\Resources\Json\JsonResource;
class Product extends JsonResource
{
    public function toArray($request)
    {
        return [
            'id' => $this->id,
            'name' => $this->title,
            'description' => $this->description,
            'created_at' => $this->created_at->format('m/d/Y'),
            'updated_at' => $this->updated_at->format('m/d/Y'),
        ];
    }
    
}
PHP

Creating Controllers

Next, we need to create three controllers to handle the auth process; first, create an API directory into the Controllers folder; after that, create three files simultaneously within the folder name them AuthController, BaseController and ProductController.

These files will individually handle login, signup and blogs crud operations.

Subsequently, add the code in the app/Http/Controllers/API/BaseController.php file:

<?php

namespace App\Http\Controllers\API;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller as Controller;

class BaseController extends Controller
{
    /**
     * success response method.
     *
     * @return \Illuminate\Http\Response
     */
    public function sendResponse($result, $message)
    {
    	$response = [
            'success' => true,
            'data'    => $result,
            'message' => $message,
        ];
        return response()->json($response, 200);
    }

    /**
     * return error response.
     *
     * @return \Illuminate\Http\Response
     */
    public function sendError($error, $errorMessages = [], $code = 404)
    {
    	$response = [
            'success' => false,
            'message' => $error,
        ];
        if(!empty($errorMessages)){
            $response['data'] = $errorMessages;
        }
        return response()->json($response, $code);
    }
}
PHP

Open and place all the suggested code into the app/Http/Controllers/API/AuthController.php file, it will amplify the user registration and signin process:

<?php
   
namespace App\Http\Controllers\API;
   
use Illuminate\Http\Request;
use App\Http\Controllers\API\BaseController as BaseController;
use Illuminate\Support\Facades\Auth;
use Validator;
use App\Models\User;
   
class AuthController extends BaseController
{
    public function signin(Request $request)
    {
        if(Auth::attempt(['email' => $request->email, 'password' => $request->password])){ 
            $authUser = Auth::user(); 
            $success['token'] =  $authUser->createToken('MyAuthApp')->plainTextToken; 
            $success['name'] =  $authUser->name;
   
            return $this->sendResponse($success, 'User signed in');
        } 
        else{ 
            return $this->sendError('Unauthorised.', ['error'=>'Unauthorised']);
        } 
    }
    public function signup(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'name' => 'required',
            'email' => 'required|email',
            'password' => 'required',
            'confirm_password' => 'required|same:password',
        ]);
   
        if($validator->fails()){
            return $this->sendError('Error validation', $validator->errors());       
        }
   
        $input = $request->all();
        $input['password'] = bcrypt($input['password']);
        $user = User::create($input);
        $success['token'] =  $user->createToken('MyAuthApp')->plainTextToken;
        $success['name'] =  $user->name;
   
        return $this->sendResponse($success, 'User created successfully.');
    }
   
}
PHP

Head over to the app/Http/Controllers/API/BlogController.php file and insert the CRUD operations code into it:

<?php
   
namespace App\Http\Controllers\API;
   
use Illuminate\Http\Request;
use App\Http\Controllers\API\BaseController as BaseController;
use Validator;
use App\Models\Product;
use App\Http\Resources\Product as ProductResource;
   
class ProductController extends BaseController
{
    public function index()
    {
        return $this->sendResponse(ProductResource::collection(Product::all()), 'Products fetched.');
    }
    
    public function store(Request $request)
    {
        $input = $request->all();
        $validator = Validator::make($input, [
            'name' => 'required',
            'description' => 'required'
        ]);
        if($validator->fails()){
            return $this->sendError($validator->errors());       
        }
        return $this->sendResponse(new ProductResource(Product::create($input)), 'Produts created.');
    }
   
    public function show($id)
    {
        $product = Product::find($id);
        if (is_null($blog)) {
            return $this->sendError('Product does not exist.');
        }
        return $this->sendResponse(new ProductResource($product), 'Product fetched.');
    }
    
    public function update(Request $request, Product $product)
    {
        $input = $request->all();
        $validator = Validator::make($input, [
            'name' => 'required',
            'description' => 'required'
        ]);
        if($validator->fails()){
            return $this->sendError($validator->errors());       
        }
        $product->name = $input['name'];
        $product->description = $input['description'];
        $product->save();
        
        return $this->sendResponse(new ProductResource($product), 'Product updated.');
    }
   
    public function destroy(Product $product)
    {
        $product->delete();
        return $this->sendResponse([], 'Product deleted.');
    }
}
PHP

Create REST API Routes

You need to use controllers to build sanctum auth api routes; we have defined the login, register post methods and resources to create auth api collectively.

Open and insert code into routes/api.php file:

<?php
  
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;
  
use App\Http\Controllers\API\AuthController;
use App\Http\Controllers\API\ProductController;
  
/*
|--------------------------------------------------------------------------
| API Routes
|--------------------------------------------------------------------------
*/
  
Route::post('login', [AuthController::class, 'signin']);
Route::post('register', [AuthController::class, 'signup']);
     
Route::middleware('auth:sanctum')->group( function () {
    Route::resource('products', ProductController::class);
});
PHP

Test Sanctum REST API in Postman

We have created the REST API using sanctum auth; further you need to start the laravel development server with the help of the php artisan command:

php artisan serve
Bash

With the help of Postman, we will test the Laravel Sanctum authentication APIs:

Test Register REST API

Open the Postman app, select the Post method from the dropdown. Enter the route or URL in the address bar, select the Body section, enter name, email, password and confirm the password and click on send to create a user using laravel sanctum auth api.

http://localhost:8000/api/register
Markup

laravel sanctum auth api

Test Login API

Add the following URL in the postman address bar, switch the method to GET, enter email and password and click on send to login a user.

http://localhost:8000/api/login
Markup

Test Login API

Set Authorization Token

Get into the Postman app’s Authorization tab, select ‘Bearer Token’ from the Type dropdown, then add the auth token that you got when logged into the app.

Set Authorization Token

Create Post with Sanctum API

Add the following URL in the postman address bar, switch the method to POST, enter title and description then click to create a post and store into the database.

http://localhost:8000/api/products
Markup

Create Post

Get Single Post

You can now see how to fetch single post using the post id and rest api, use the given below url:

http://localhost:8000/api/products/{id}
Markup

Get Single Post

Fetch All Posts

You can fetch all the posts at once, hence use the following REST API with GET method to get all the records.

http://localhost:8000/api/products
Markup

Fetch App Posts

Update Post

Update a post using sanctum auth restful api, add the following route with Put method to update a single record into the database.

http://localhost:8000/api/products/{id}
Markup

Update Record

Delete Record

To delete a record set the method to delete and use the following url:

http://localhost:8000/api/products/{id}
Markup

Delete Record

Conclusion

The Laravel Sanctum authentication tutorial is over; throughout this detailed guide, you explored bit by bit how to create and test authentication REST API in laravel with the help of Sanctum auth package and Postman api testing tool.

When it comes to security, flexibility, and ease of use, there is nothing better than Sanctum auth api.

You may also take the help of Laravel sanctum auth API to add authentication in your next laravel project. We assume you liked this comprehensive example, so don’t forget to share it with others.

Categorized in:

Tagged in: