DEV Community

shaileshjadav
shaileshjadav

Posted on

Laravel 8 REST API Authentication using Sanctum

Sanctum is Laravel package for authentication for single page application(SPAs), mobile applications and basic token based APIs.

For SPA authentication, Sanctum uses Laravel’s built in cookie based authentication services. Means while working with front end technologies like react, Angular Sanctum create cookie and save in browser by using this accomplish authentication. For token based Rest APIs, Sanctum create token and save in personal_access_tokens table. while authentication try to match with this table if token not found then authentication goes to failed.

Let’s install sanctum package first and then create a register, login, logout APIs and protect our routes.

Installation:

composer require laravel/sanctum
Enter fullscreen mode Exit fullscreen mode

This command install package using composer.

php artisan vendor:publish --provider="Laravel\Sanctum\SanctumServiceProvider"
Enter fullscreen mode Exit fullscreen mode

Next run this command, it creates migration files for personal_access_token table and configuration files for sanctum. You can check this file in database->migrations folder named like 2019_12_14_000001_create_personal_access_tokens_table.php

php artisan migrate
Enter fullscreen mode Exit fullscreen mode

Then run this command, this create a personal_access_token table in database in which Sanctum store API tokens.

Configuration:

Go to app->Http->Kernal.php and add given lines to apis array of middlewareGroups.

'api' => [
    \Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class,
    'throttle:api',
    \Illuminate\Routing\Middleware\SubstituteBindings::class,
],

Enter fullscreen mode Exit fullscreen mode

Note: If you get too many attempts error while calling APIs multiple time. Then comment ‘throttle:api’ line and keep default as it is like below screenshot.
image

Next go to UserModel.php file and add set below code so usermodel can use HasApiTokens to issue token.

use Laravel\Sanctum\HasApiTokens;
use HasApiTokens, HasFactory, Notifiable;
Enter fullscreen mode Exit fullscreen mode

Note in my project hasFactory trait not autoloaded.
image

Create Crontroller

php artisan make:controller Api\AuthController

This command create authController in Api folder of controller’s folder.

Set routes in routes->api.php file

use App\Http\Controllers\Api\AuthController;
Route::post("/register",[AuthController::class,'register']);
Route::post("/login",[AuthController::class,'login']);
Enter fullscreen mode Exit fullscreen mode

Let’s make register function in authController. in this new user and token creates and given to response.

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

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

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

        $response = [
            'status'=>true,
            'message'=>'registered successfully!',
            'data' =>[
                'user'=>$user,
                'token'=>$token
            ]
        ];
        return response($response,201);
    }
Enter fullscreen mode Exit fullscreen mode

And call api using postman as below:
image

Login Function:

public function login(Request $request){
        $fields = $request->validate([
            'email'=>'required|string|email',
            'password' =>'required|confirmed'
        ]);
        //check email
        $user = User::where('email',$fields['email'])->first();
        //check password
        if(!$user || !Hash::check($fields['password'],$user->password)){
            return response(['status'=>false,'message'=>'invalid email or password'],401);
        }

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

        $response = [
            'status'=>true,
            'message'=>'Login successful!',
            'data' =>[
                'user'=>$user,
                'token'=>$token
            ]
        ];
        return response($response,201);
    }
Enter fullscreen mode Exit fullscreen mode

Call login api as below:
image

Now Let’s create authenticate routes in api-routes file as below.

Route::group(['middleware'=>['auth:sanctum']],function(){
    Route::post("/logout",[AuthController::class,'logout']);
});
Enter fullscreen mode Exit fullscreen mode

In above routes sanctum middleware validates token from Authorization header.

Let’s make function logout in authController.

public function logout(Request $request){
        auth()->user()->tokens()->delete();
        $response = [
            'status'=>true,
            'message'=>'Logout successfully',
        ];
        return response($response,201);
    }

Enter fullscreen mode Exit fullscreen mode

image

While token is not set/validate then will receive below response.

{
"message": "Unauthenticated."
}

Note: Set header Accept:application/json to get response in json for above apis and Authorization header with Bearer .

Discussion (0)