How to use Laravel Sanctum for API Authentication
Tags: laravel, webdev, programming, tutorial
Published: 2022-05-05 13:51:56

## Make REST API AUTHENTICATION in LARAVEL 9 USING LARAVEL SANCTUM

Laravel Sanctum provides a featherweight authentication system for SPAs (single page applications), mobile applications, and simple, token based APIs.

## Installation Steps
If you are not using LARAVEL 9 you need to install LARAVEL Sanctum Otherwise you can skip the installation step.

### Step 1
Install via composer

```php
composer require laravel/sanctum
```
### Step 2
Publish the Sanctum Service Provider

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

### Step 3
Migrate The Database
```php
php artisan migrate
```

## USING SANCTUM IN LARAVEL

### User `HasApiTokens` Trait in `App\Models\User`

In Order to use Sanctum we need to use `HasApiTokens` Trait Class in User Model.
User Model should look like.
```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 HasApiTokens, HasFactory, Notifiable;

    /**
     * The attributes that are mass assignable.
     *
     * @var array<int, string>
     */
    protected $fillable = [
        'name',
        'email',
        'password',
    ];

    /**
     * The attributes that should be hidden for serialization.
     *
     * @var array<int, string>
     */
    protected $hidden = [
        'password',
        'remember_token',
    ];

    /**
     * The attributes that should be cast.
     *
     * @var array<string, string>
     */
    protected $casts = [
        'email_verified_at' => 'datetime',
    ];
}
```
### API Authentication Routes

Create `AuthController` to handle all authentication realted to API
```php
php artisan make:controller Api\\AuthController
```

In `routes\api.php` file update the API

```php
Route::post('/auth/register', [AuthController::class, 'createUser']);
Route::post('/auth/login', [AuthController::class, 'loginUser']);
```

Now update `AuthContoller` with
```php
<?php

namespace App\Http\Controllers\Api;

use App\Models\User;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Validator;

class AuthController extends Controller
{
    /**
     * Create User
     * @param Request $request
     * @return User 
     */
    public function createUser(Request $request)
    {
        try {
            //Validated
            $validateUser = Validator::make($request->all(), 
            [
                'name' => 'required',
                'email' => 'required|email|unique:users,email',
                'password' => 'required'
            ]);
    
            if($validateUser->fails()){
                return response()->json([
                    'status' => false,
                    'message' => 'validation error',
                    'errors' => $validateUser->errors()
                ], 401);
            }

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

            return response()->json([
                'status' => true,
                'message' => 'User Created Successfully',
                'token' => $user->createToken("API TOKEN")->plainTextToken
            ], 200);
            
        } catch (\Throwable $th) {
            return response()->json([
                'status' => false,
                'message' => $th->getMessage()
            ], 500);
        }
    }

    /**
     * Login The User
     * @param Request $request
     * @return User
     */
    public function loginUser(Request $request)
    {
        try {
            $validateUser = Validator::make($request->all(), 
            [
                'email' => 'required|email',
                'password' => 'required'
            ]);
    
            if($validateUser->fails()){
                return response()->json([
                    'status' => false,
                    'message' => 'validation error',
                    'errors' => $validateUser->errors()
                ], 401);
            }

            if(!Auth::attempt($request->only(['email', 'password']))){
                return response()->json([
                    'status' => false,
                    'message' => 'Email & Password does not match with our record.',
                ], 401);
            }

            $user = User::where('email', $request->email)->first();

            return response()->json([
                'status' => true,
                'message' => 'User Logged In Successfully',
                'token' => $user->createToken("API TOKEN")->plainTextToken
            ], 200);

        } catch (\Throwable $th) {
            return response()->json([
                'status' => false,
                'message' => $th->getMessage()
            ], 500);
        }
    }
}
```

### Protect API With Authentication we need to use `auth:sanctum` middleware.

```php
Route::apiResource('posts', PostController::class)->middleware('auth:sanctum');
```

Here are the results.

![Register User](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/j3payp41pzmr2lcuuuvx.png)

![Login API](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/685yuqku1c8mz1xcaimc.png)

![GET API](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/up6yc28lo9j3vccl5r7y.png)

The complete Tutorial is below in the video.

{% youtube GAB_BqFZNOA %}

If you face any issue while making REST API, please comment your query.


Thank You for Reading

Reach Out To me.
[Twitter](https://twitter.com/techtoolindia)
[Instagram](https://www.instagram.com/techtoolindia/)
[TechToolIndia YouTube Channel](https://www.youtube.com/channel/UCOy6o08Yn9DtXMKqxhD9ivA)