DEV Community

Siddhu
Siddhu

Posted on

Laravel Sanctum

I want to build an authentication system for both WEB and Mobile using API. After searching for good framework, Finally I choose Laravel. It is well suited for my requirement and one of the best frameworks, large community and well documented.

In this article, I'll explain step by step flow that how to integrate Laravel Sanctum. Mainly I focus on API base authentication.

Use cases

  1. API Tokens
  2. Web Authentication
  3. You can use both (API Tokens & Web Authentication)

API Tokens

Its generate a simple API token for your user without complication of OAuth. This token have expire very long time (years). All tokens store in single database table and authenticating incoming HTTP requests via the Authorization header which should contain a valid API token.

Web Authentication

Laravel Sanctum will only attempt to authenticate using cookies when the incoming request originates from your own frontend. When you call HTTP request, it will first check for an authentication cookie and, if none is present, Sanctum will then examine the Authorization header for a valid API token.

You can use both (API Tokens & Web Authentication)

It's okay to use single service either API Tokens or Web Authentication, it doesn't mean that you should mandatory use both services. You can use anyway based on your requirement.

Laravel installation

composer create-project laravel/laravel laravel_sanctum
after installation done, start server to check installation successfully done.
php artisan serve

Alt Text

On the latest version of Laravel has already include Laravel Sanctum.

Alt Text

However, If you are using old version of Laravel, You can do it manually.

In your application's composer.json file does not include laravel/sanctum then add it on composer.json' file and run commandcomposer update` or follow the link instructions Larevel-sanctum.

Database config

Open .env file and add your database details, In my case I'm using MySQL.


    DB_CONNECTION=mysql
    DB_HOST=127.0.0.1
    DB_PORT=3306
    DB_DATABASE=laravel_sanctum
    DB_USERNAME=root
    DB_PASSWORD=

After database configuration done. Run the command php artisan migrate. it will create a default database tables from Laravel.

Now you should add Sanctum's middleware to your api middleware group at app/Http/Kernel.php.

 protected $middlewareGroups = [
        'web' => [
            \App\Http\Middleware\EncryptCookies::class,
            \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
            \Illuminate\Session\Middleware\StartSession::class,
            // \Illuminate\Session\Middleware\AuthenticateSession::class,
            \Illuminate\View\Middleware\ShareErrorsFromSession::class,
            \App\Http\Middleware\VerifyCsrfToken::class,
            \Illuminate\Routing\Middleware\SubstituteBindings::class,
        ],
        'api' => [
            \Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class,
            'throttle:api',
            \Illuminate\Routing\Middleware\SubstituteBindings::class,
        ],
    ];

Next, you should 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"

And it will create migration file for personal access token

image

Sanctum allows you to issue API tokens / personal access tokens that may be used to authenticate API requests to your application. When making requests using API tokens, the token should be included in the Authorization header as a Bearer token.

To begin issuing tokens for users, your User model should use the Laravel\Sanctum\HasApiTokens trait:

use Laravel\Sanctum\HasApiTokens;

class User extends Authenticatable
{
    use HasApiTokens, HasFactory, Notifiable;
}

Create a controller for user authentication

php artisan make:controller Authcontroller 

image

it will AuthController, In the AuthController add the follow lines

Request
use Illuminate\Http\Request;

Response
use Illuminate\Http\Response;

This is for password encrpt
use Illuminate\Support\Facades\Hash;

Your user model
use App\Models\User;

Register User

public function register(Request $request)
{
    $fields = $request->validate([
        "name" => 'required|string',
        "email" => 'required|string|unique:users,email',
        "password" => 'required|string|confirmed'
    ]);

    $user = User::create([
        'name' => $fields['name'],
        'email' => $fields['email'],
        'password' => bcrypt( $fields['password'] ),
    ]);

    $token = $user->createToken('myapptoken')->plainTextToken;

    $response = [
        'user' => $user,
        'token' => $token,
    ];

    return response($response, 201);
}

Login

public function login(Request $request)
{
    $fields = $request->validate([
        "email" => 'required|string',
        "password" => 'required|string',
    ]);

    // Check Email
    $where = ["email"=>$fields['email']];
    $user = User::where($where)->first();

    // Check Password
    if(!$user || !Hash::check($fields['password'], $user->password))
    {
       return response([
           'message' => "Bad credentials"
       ],401);
    }

    $token = $user->createToken('myapptoken')->plainTextToken;

    $response = [
        'user'=>$user,
        'token'=>$token
    ];

    return response($response,201);
}

logout

public function logout(Request $request)
{
    auth()->user()->tokens()->delete();

    $response = [
        'message' => 'logged out'
    ];

    return response($response,201);
}

Now go to routes\api.php and config Public/Protected routes like as shown in below

//Public routes
Route::post('/register', [AuthController::class,'register']);
Route::post('/login', [AuthController::class,'login']);


//Protected routes
Route::group(['middleware'=>['auth:sanctum']], function () {
    Route::post('/logout', [AuthController::class,'logout']);
});

It time to call API's. For this demo I'm using Postman

image

This request I have sent without post data to check the validations, And you must set the headers otherwise you will encounter with errors. Accept:Application\Json

Let register an User

image

You are successfully configured Laravel Sanctum :)

In the response you will receive personal access token.

image

In this response you can notice that we have received token, Use that token for all protected services. You should pass that token in headers as bearer token for Authorization.

I also give an example for Logout.

image

If you hit protected API without token, That request is unauthorized.

Now I added Bearer token in request, Then I'm successfully logout.

image

Please feel free to ask me anything on this topic!

Top comments (0)