REST API Authentication using Sanctum in LARAVEL 10

Spread the love

Hello Guys,

In this brief tutorial, we will explore REST API Authentication using Sanctum within the Laravel 10 Fortress framework. We’ll delve into the details of this Sanctum-based Laravel 10 REST API, focusing on the Sanctum SPA API example. We’ll also provide an in-depth look at the Sanctum API sample for Laravel 10. Let’s dive into the specifics.

Laravel 10 Sanctum offers a straightforward authentication mechanism suitable for single-page applications (SPAs), mobile apps, and simple APIs that rely on tokens. With Sanctum, users of your application can easily generate multiple API tokens for their accounts.

If you’re looking to create an API for your mobile application and want to learn how to develop a REST API using Laravel 10 and Sanctum, you’ve come to the right place. Don’t worry if you’re new to this; we’ve prepared step-by-step instructions for you.

To create a RESTful API example in your Laravel 10 application with REST API Authentication using Sanctum, follow the simple steps outlined below.

Step 1: Install Laravel 10

While it’s not mandatory, you can still go ahead and execute the following command if you haven’t yet established your Laravel application:

Also Read: How to Create Custom Helper Functions in LARAVEL 10

composer create-project laravel/laravel example-app

Step 2: Use Sanctum

In this guide, we will demonstrate how to install Sanctum using the Composer package manager. To begin, simply enter the following command into your terminal:

composer require laravel/sanctum

To ensure your configuration file is properly published following a successful package installation, you should employ the following command:

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

To establish fresh sanctum tables within our database, it’s essential to acquire the default migration. To do so, simply execute the following command:

php artisan migrate

Next, we’ll incorporate the Sanctum API middleware into your system. Let’s proceed by adding it as shown below:

Also Read: How to Add Foreign Key in MIGRATION using Laravel?

app/Http/Kernel.php
....

'api' => [

    \Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class,

    'throttle:api',

    \Illuminate\Routing\Middleware\SubstituteBindings::class,

],

....

Step 3: Sanctum Configuration

In this step, it’s crucial to configure three key elements: the model, the service provider, and the authentication configuration file. You simply need to implement the recommended adjustments to the configuration file.

Additionally, we’ve incorporated the Sanctum HasApiTokens class into the model, enhancing its functionality.

Furthermore, within the auth.php file, we’ve introduced essential API authentication configurations to improve security and access control.

app/Models/User.php

Also Read: How to Rollback Migration in Laravel?

<?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',
    ];
}

Step 4: Add Product Table and Model

Next, in Laravel 10, we should create a migration for the products table using the ‘php artisan’ command. To begin, execute the following command:

php artisan make:migration create_products_table

After executing this command, you’ll discover a file within the database/migrations directory. To create the products table, it’s essential to incorporate the provided code into your migration file.

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

Once you’ve completed the migration setup, initiate the execution of the preceding migration by utilizing the subsequent command:

php artisan migrate

To establish a product model for products after generating the “products” table, follow these steps:

  1. Navigate to the directory app/Models/ and create a new file named “Product.php“.
  2. Open the newly created “Product.php” file and insert the provided text below. This will enable the creation of a product model:
app/Models/Product.php

Also Read: how to Create Custom Artisan Command in LARAVEL

<?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'
    ];

}

By following these instructions, you’ll successfully create a product model for the “products” table.

Step 5: Create API Routes

In this phase, we will be creating API routes for login, registration, and product REST APIs. Therefore, it’s time to enhance the file by adding a fresh route.

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

Step 6: Create Controller Files

In the next phase, we’ll be crafting three essential controllers: BaseController, ProductController, and RegisterController. To maintain a well-organized structure, we’ve introduced a dedicated ‘API’ folder within the Controllers directory, exclusively for housing our API controller. Let’s proceed to create and configure these controllers.

app/Http/Controllers/API/BaseController.php

Also Read: How To Send Email In Laravel 9

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

}
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']);
        } 
    }
}
app/Http/Controllers/API/ProductController.php

Also Read: How to use laravel cookies – Get, Set, Delete with example

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

}

Step 7: Create Eloquent API Resources

In the realm of web development, Laravel 10 represents a pivotal milestone, especially when crafting a robust REST API. Leveraging the power of Eloquent API resources enhances the API creation process. These resources facilitate the creation of uniform response structures for your model objects. To implement this in your project, navigate to the ProductController file and employ the subsequent command for seamless execution:

php artisan make:resource ProductResource

Presently, a fresh file and directory have been created along the specified pathway:

app/Http/Resources/ProductResource.php

Also Read: Laravel 10 CRUD Example step by step

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

}

Run Laravel App:

Once you’ve successfully completed all the essential steps, it’s time to proceed by executing the following command. Simply enter it and press “Enter” to initiate the launch of your Laravel application:

php artisan serve

Visit Postman immediately and review the listed APIs. Make certain to utilize the specified headers outlined below within the details API.

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

Discover the List of URL Routes Based on Verbs:

Also Read: How To Generate PDF Files using DomPDF In Laravel 9

You can now effortlessly access and utilize the previously mentioned URL:

1) Register API: Verb:GET, URL:http://localhost:8000/api/register

2) Login API: Verb:GET, URL:http://localhost:8000/api/login

3) Product List API: Verb:GET, URL:http://localhost:8000/api/products

4) Product Create API: Verb:POST, URL:http://localhost:8000/api/products

5) Product Show API: Verb:GET, URL:http://localhost:8000/api/products/{id}

6) Product Update API: Verb:PUT, URL:http://localhost:8000/api/products/{id}

7) Product Delete API: Verb:DELETE, URL:http://localhost:8000/api/products/{id}

Your quest for the best Laravel blog ends here, where expert knowledge meets curated excellence.

Leave a Comment