Laravel 10 REST API Authentication Using Sanctum

  Dec 2023
  ITSolutionsGuides
  Category: Laravel
Laravel 10 REST API Authentication Using Sanctum

Hi Developers,

Lets see How to use Laravel 10 REST API Authentication Using Sanctum. for this we are going to use the laravel/sanctum package for creating the REST API.
"ITSolutionsGuides" serves as an invaluable resource and guide, providing expertise and insights for developers navigating the ever-evolving realm of technology. One noteworthy focus is on Laravel 10 Sanctum API authentication. The platform showcases a comprehensive example, elucidating the intricacies of Laravel 10 Rest API implementation using Sanctum. Diving deeper into the Laravel 10 Sanctum spa API example, the guide meticulously outlines steps to seamlessly integrate Sanctum for robust SPA authentication. Developers can glean practical knowledge from the detailed Laravel 10 Sanctum API examples, shedding light on REST API implementations and authentication methodologies. The guide's emphasis on Laravel 10 Sanctum API token tutorial is particularly beneficial. It demystifies the token-centric approach, empowering developers to fortify their applications with secure authentication mechanisms. With a focus on clarity and practicality, "ITSolutionsGuides" emerges as an indispensable companion in navigating Laravel 10 Sanctum API authentication challenges.
Sanctum is a lightweight Laravel package that helps you implement simple and secure token-based authentication for your REST APIs. It integrates seamlessly with your existing project and allows you to easily grant access to users and applications with personal access tokens.

Lets Install Package

Lets install the laravel/sanctum package using the the following commands,

composer require laravel/sanctum

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

php artisan migrate

Lets Install Package

lets add middleware for sanctum api and register in Kernel.php

app/Http/Kernel.php

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

Lets Configure Sanctum

app/Models/User.php

<?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;
use Laravel\Sanctum\HasApiTokens;
  
class User extends Authenticatable
{
    use HasFactory, Notifiable, HasApiTokens;
  
    /**
     * 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',
    ];
}

Lets Create Migration

Lets create the model and migration together using the following artisan command,

php artisan make:model Product -m

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

Lets Edit Model

app/Models/Product.php

<?php
  
namespace App\Models;
  
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
  
class Product extends Model
{
    use HasFactory;
  
    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $fillable = [
        'name', 'detail'
    ];
}

Lets Create API Routes

Lets migrate the table using the following artisan command
php artisan migrate

Lets create the routes Since we are creating the API Routes we should use the api.php file Note : Routes inside api.php file does no require csrf token verification

routes/api.php

<?php
  
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;
  
use App\Http\Controllers\API\RegisterController;
use App\Http\Controllers\API\ProductController;
  
/*
|--------------------------------------------------------------------------
| API Routes
|--------------------------------------------------------------------------
|
| Here is where you can register API routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| is assigned the "api" middleware group. Enjoy building your API!
|
*/
  
  
Route::controller(RegisterController::class)->group(function(){
    Route::post('register', 'register');
    Route::post('login', 'login');
});
        
Route::middleware('auth:sanctum')->group( function () {
    Route::resource('products', ProductController::class);
});

Lets Create Controller

Lets create the controller using the following artisan command ,
php artisam make:controller BaseController
We are going to make the common controller for creating the format of the sending API response message. While sending any API response through any controller we should extent this controller for sending the common API response format

For detailed explanation about controller
app/Http/Controllers/API/BaseController.php

<?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);
    }
}

Lets Create Controller

Lets create the controller using the following artisan command ,
php artisam make:controller RegisterController and extend to the BaseController for sending the common API response format

For detailed explanation about controller

app/Http/Controllers/API/RegisterController.php

<?php
   
namespace App\Http\Controllers\API;
   
use Illuminate\Http\Request;
use App\Http\Controllers\API\BaseController as BaseController;
use App\Models\User;
use Illuminate\Support\Facades\Auth;
use Validator;
use Illuminate\Http\JsonResponse;
   
class RegisterController extends BaseController
{
    /**
     * Register api
     *
     * @return \Illuminate\Http\Response
     */
    public function register(Request $request): JsonResponse
    {
        $validator = Validator::make($request->all(), [
            'name' => 'required',
            'email' => 'required|email',
            'password' => 'required',
            'c_password' => 'required|same:password',
        ]);
   
        if($validator->fails()){
            return $this->sendError('Validation Error.', $validator->errors());       
        }
   
        $input = $request->all();
        $input['password'] = bcrypt($input['password']);
        $user = User::create($input);
        $success['token'] =  $user->createToken('MyApp')->plainTextToken;
        $success['name'] =  $user->name;
   
        return $this->sendResponse($success, 'User register successfully.');
    }
   
    /**
     * Login api
     *
     * @return \Illuminate\Http\Response
     */
    public function login(Request $request): JsonResponse
    {
        if(Auth::attempt(['email' => $request->email, 'password' => $request->password])){ 
            $user = Auth::user(); 
            $success['token'] =  $user->createToken('MyApp')->plainTextToken; 
            $success['name'] =  $user->name;
   
            return $this->sendResponse($success, 'User login successfully.');
        } 
        else{ 
            return $this->sendError('Unauthorised.', ['error'=>'Unauthorised']);
        } 
    }
}

Lets Create Controller

Lets create the controller using the following artisan command ,
php artisam make:controller ProductController and extend to the BaseController for sending the common API response format

For detailed explanation about controller

app/Http/Controllers/API/ProductController.php

<?php
   
namespace App\Http\Controllers\API;
   
use Illuminate\Http\Request;
use App\Http\Controllers\API\BaseController as BaseController;
use App\Models\Product;
use Validator;
use App\Http\Resources\ProductResource;
use Illuminate\Http\JsonResponse;
   
class ProductController extends BaseController
{
    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function index(): JsonResponse
    {
        $products = Product::all();
    
        return $this->sendResponse(ProductResource::collection($products), 'Products retrieved successfully.');
    }
    /**
     * Store a newly created resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function store(Request $request): JsonResponse
    {
        $input = $request->all();
   
        $validator = Validator::make($input, [
            'name' => 'required',
            'detail' => 'required'
        ]);
   
        if($validator->fails()){
            return $this->sendError('Validation Error.', $validator->errors());       
        }
   
        $product = Product::create($input);
   
        return $this->sendResponse(new ProductResource($product), 'Product created successfully.');
    } 
   
    /**
     * Display the specified resource.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function show($id): JsonResponse
    {
        $product = Product::find($id);
  
        if (is_null($product)) {
            return $this->sendError('Product not found.');
        }
   
        return $this->sendResponse(new ProductResource($product), 'Product retrieved successfully.');
    }
    
    /**
     * Update the specified resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function update(Request $request, Product $product): JsonResponse
    {
        $input = $request->all();
   
        $validator = Validator::make($input, [
            'name' => 'required',
            'detail' => 'required'
        ]);
   
        if($validator->fails()){
            return $this->sendError('Validation Error.', $validator->errors());       
        }
   
        $product->name = $input['name'];
        $product->detail = $input['detail'];
        $product->save();
   
        return $this->sendResponse(new ProductResource($product), 'Product updated successfully.');
    }
   
    /**
     * Remove the specified resource from storage.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function destroy(Product $product): JsonResponse
    {
        $product->delete();
   
        return $this->sendResponse([], 'Product deleted successfully.');
    }
}

Lets Create Eloquent API Resources

Lets create the resource using the following artisan command,
php artisan make:resource ProductResource the API resources are created or used to make the API response customize something like changing the column name or create any array etc.

app/Http/Resources/ProductResource.php

<?php
  
namespace App\Http\Resources;
  
use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\JsonResource;
  
class ProductResource extends JsonResource
{
    /**
     * Transform the resource into an array.
     *
     * @return array

     */
    public function toArray(Request $request): array
    {
        return [
            'id' => $this->id,
            'name' => $this->name,
            'detail' => $this->detail,
            'created_at' => $this->created_at->format('d/m/Y'),
            'updated_at' => $this->updated_at->format('d/m/Y'),
        ];
    }
}

Lets Run Application

Lets run the Laravel Application using the following artisan command

php artisan serve

Lets Set Headers

Since we are using the Sanctum package we need to update the headers and the Authorization token in the postman. While we once login the token will be generated in the postman we need to update the token generated in the headers in order to get authorized.

'headers' => [

    'Accept' => 'application/json',
    'Authorization' => 'Bearer '.$accessToken,

]

Postman Routes

The Routes that are used in postman to access the data

GET, URL:http://localhost:8000/api/register

GET, URL:http://localhost:8000/api/login

GET, URL:http://localhost:8000/api/products

POST, URL:http://localhost:8000/api/products

GET, URL:http://localhost:8000/api/products/{id}

PUT, URL:http://localhost:8000/api/products/{id}

DELETE, URL:http://localhost:8000/api/products/{id}

We hope it helps everyone. Thanks for supporting ITSolutionsGuides and keep supporting us also follow us in social media platforms.

Subscribe for NewsLetter

Be the first to know about releases and tutorial news and solutions.

We care about your data in our privacy policy.

ITSolutionsGuides

ITSolutionsGuides was started mainly to provide good and quality web solutions for all the developers. We provide tutorials to support all the developers and also we try to provide solutions to the errors we face while coding.

Contact US

ITSolutionsGuides, provide users with an easy-to-use form to reach out for support or inquiries.

whatsapp  gmail  instagram-new--v1  facebook-circled  twitter-circled  linkedin  github  pinterest 

Copyright © 2023 - 2024 All rights reserved | ITSolutionsGuides