Optimized for versions:

  • laravel/framework 9.11
  • laravel/passport: 10.4

To create a Laravel API with Passport authentication:

Create a Laravel project

laravel new api

In Laravel 11, run the command to install the API routes.

php artisan install:api

Inside the api folder created install laravel/passport

composer require laravel/passport

Run the migrations

php artisan migrate

Install passport

php artisan passport:install

Update the configuration in config/auth.php

'guards' => [
    'web' => [
        'driver' => 'session',
        'provider' => 'users',
    ],
    'api' => [
        'driver' => 'passport',
        'provider' => 'users',
    ],
],

In the User.php model, make sure to add the HasApiTokens trait (and if the trait is there already, make sure it is the trait from Passport and not Sanctum

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Laravel\Passport\HasApiTokens;//<-------------------------Make sure this is Passport

class User extends Authenticatable
{
    use HasApiTokens, HasFactory, Notifiable;//<---------------------------Make sure HasApiTokens trait is here

Create the AuthController

php artisan make:controller AuthController

In the controller add the following contents

<?php

namespace App\Http\Controllers;

use Carbon\Carbon;
use Illuminate\Http\Request;
use App\Models\User;
use Illuminate\Support\Facades\Auth;

class AuthController extends Controller
{
    /**
     * Register api
     *
     * @return \Illuminate\Http\Response
     */
    public function register(Request $request)
    {
        $request->validate([
            'name' => 'required',
            'email' => 'required|email',
            'password' => 'required',
            'c_password' => 'required|same:password',
        ]);

        $input = $request->all();
        $input['password'] = bcrypt($input['password']);
        $user = User::create($input);

        $tokenResult = $user->createToken('Personal Access Token');

        return response([
            'token' => $tokenResult->accessToken,
            'expires_at' => Carbon::parse(
                $tokenResult->token->expires_at
            )->toDateTimeString()
        ], 200);
    }

    /**
     * Login api
     *
     * @return \Illuminate\Http\Response
     */
    public function login(Request $request)
    {
        if(Auth::attempt(['email' => $request->email, 'password' => $request->password])){
            $user = Auth::user();
            $tokenResult = $user->createToken('Personal Access Token');

            return response([
                'token' => $tokenResult->accessToken,
                'expires_at' => Carbon::parse(
                    $tokenResult->token->expires_at
                )->toDateTimeString()
            ], 200);
        }
        else{
            return response([
                "message" => "Unauthorised."
            ], 401);
        }
    }

    /**
     * Logout user (Revoke the token)
     *
     * @return [string] message
     */
    public function logout(Request $request)
    {
        $request->user()->token()->revoke();

        return response()->json([
            'message' => 'Successfully logged out'
        ]);
    }
}

And last but not least, add the routes pointing the methods to the controller.

<?php

namespace App\Http\Controllers;

use Illuminate\Support\Facades\Route;

Route::group([
    'prefix' => 'auth',
], function (){
    Route::post('register', [AuthController::class, 'register']);
    Route::post('login', [AuthController::class, 'login']);

    Route::group([
        'middleware' => 'auth:api',
    ], function () {
        Route::post('logout', [AuthController::class, 'logout']);

        Route::get('test', function (){
            return response([
                "message" => 'Authenticated!'
            ], 200);
        });
    });
});

Any authenticated endpoint should be placed behind the auth:api middleware like the test example.

BONUS: Postman File

Download the above postman collection and import into Postman to follow along.

Hit the register endpoint to register your user.

The registration already returns a token you can use.

Lets test the login endpoint with the user we just registered:

With the token in this response you can pass it to the authenticated endpoints. There is 2 authenticated endpoints in the collection, Test and Logout. Lets checkout the test endpoint. Make sure the Authorization is Bearer Token and that you are passing the token given in the endpoints before.

Now lets hit the logout endpoint. Make sure you also add the Bearer Token to this endpoint.

As you can see the response says logged out. This means the Token has been revoked and is now useless. Let’s try hitting the test endpoint again.

As you can see by the error code 401 and the message we get Unauthenticated.

Leave a Reply

Your email address will not be published. Required fields are marked *