Laravel API authentication using passport

Laravel Passport provides a full OAuth2 server implementation for your Laravel application in a matter of minutes.


Introduction

Laravel Passport provides a full OAuth2 server implementation for your Laravel application in a matter of minutes. Passport is built on top of the League OAuth2 server that is maintained by Andy Millington and Simon Hamp.


Passport Or Sanctum?

Before getting started, you may wish to determine if your application would be better served by Laravel Passport or Laravel Sanctum. If your application absolutely needs to support OAuth2, then you should use Laravel Passport.

However, if you are attempting to authenticate a single-page application, mobile application, or issue API tokens, you should use Laravel Sanctum. Laravel Sanctum does not support OAuth2; however, it provides a much simpler API authentication development experience.


Installation

  1. To use laravel/passport, your system requires ext-sodium extension installed. To make sure, you have added that extension, Open php.ini and check below extension should not be commented:
  2. extension=sodium
  3. You may install Laravel Passport via the install:api Artisan command:
  4. php artisan install:api --passport

    This command will publish and run the database migrations necessary for creating the tables your application needs to store OAuth2 clients and access tokens. The command will also create the encryption keys required to generate secure access tokens.

  5. After running the install:api command, add the Laravel\Passport\HasApiTokens trait to your App\Models\User model. This trait will provide a few helper methods to your model that allow you to inspect the authenticated user's token and scopes:
  6. <?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;
    
    class User extends Authenticatable
    {
        use HasApiTokens, HasFactory, Notifiable;
    }
  7. install:api command will add routes/api.php file. That should be included in the bootstrap/app.php file inside withRouting as below
  8. return Application::configure(basePath: dirname(__DIR__))
      ->withRouting(
        web: __DIR__ . '/../routes/web.php',
        api: __DIR__ . '/../routes/api.php', // Add this if not added by install:api
        commands: __DIR__ . '/../routes/console.php',
        health: '/up',
      )
  9. Finally, in your application's config/auth.php configuration file, you should API authentication guard and set the driver option to passport. This will instruct your application to use Passport's TokenGuard when authenticating incoming API requests:
  10. 'guards' => [
        'web' => [
            'driver' => 'session',
            'provider' => 'users',
        ],
    
        'api' => [
            'driver' => 'passport',
            'provider' => 'users',
        ],
    ],
  11. Finally, you should run your database migrations. Passport will create one database table in which to store API tokens:
  12. php artisan migrate

Deploying Passport

When deploying Passport to your application's servers for the first time, you will likely need to run the passport:keys command. This command generates the encryption keys Passport needs in order to generate access tokens. The generated keys are not typically kept in source control:

php artisan passport:keys

If necessary, you may define the path where Passport's keys should be loaded from. You may use the Passport::loadKeysFrom method to accomplish this. Typically, this method should be called from the boot method of your application's App\Providers\AppServiceProvider class:

/**
* Bootstrap any application services.
*/
public function boot(): void
{
    Passport::loadKeysFrom(__DIR__.'/../secrets/oauth');
}

Passport Authentication

We'll create simple user authentication methods via Laravel passport below.

  1. Create Route: Create routes into routes/api.php that point to AuthController:
  2. <?php
    
    use Illuminate\Http\Request;
    use Illuminate\Support\Facades\Route;
    use App\Http\Controllers\AuthController;
    
    // Open Routes
    Route::post('/register', [AuthController::class, 'register']);
    Route::post('/login', [AuthController::class, 'login']);
    
    // Protected Routes
    Route::group(['middleware' => 'auth:api'], function () {
      Route::get('/profile', [AuthController::class, 'profile']);
      Route::get('/logout', [AuthController::class, 'logout']);
    });
  3. Create Controller: Now, we have to create a controller that handles all API requests. Follow below artisan command to create a new controller:
  4. php artisan make:controller AuthController
  5. Register User: We'll implement a simple method to register a user:
  6. <?php
    
    namespace App\Http\Controllers;
    
    use App\Http\Controllers\Controller;
    use Illuminate\Http\Request;
    use App\Models\User;
    
    class AuthController extends Controller
    {
    
      // POST [ name, email, password ]
      public function register(Request $request)
      {
          $request->validate([
              'name' => 'required|string',
              'email' => 'required|string|email|unique:users',
              'password' => 'required|string|confirmed',
              'password_confirmation'=>'required|same:password',
          ]);
    
          $user = User::create([
              'name' => $request->name,
              'email' => $request->email,
              'password' => bcrypt($request->password)
          ]);
    
          return response()->json([
            'status' => true, // 'error
            'message' => 'User created successfully',
            'data' => []
          ]);
        }
      }

    TEST register user API using postman

    register
  7. Login User:
  8. Creating a Personal Access Client: Before your application can issue personal access tokens, you will need to create a personal access client.

    php artisan passport:client --personal

    In the file AuthController.php, create a simple login method that generates API token via passport:

    <?php
    
    namespace App\Http\Controllers;
    
    use App\Http\Controllers\Controller;
    use Illuminate\Http\Request;
    use App\Models\User;
    use Illuminate\Support\Facades\Hash;
    public function login(Request $request)
    {
      $request->validate([
        'email' => 'required|string|email',
        'password' => 'required|string'
      ]);
    
      // User object
      $user = User::where("email", $request->email)->first();
    
      if(!empty($user)){
        // User exists
        if(Hash::check($request->password, $user->password)){
          // Password matched
          $token = $user->createToken("myAccessToken")->accessToken;
    
          return response()->json([
            "status" => true,
            "message" => "Login successful",
            "token" => $token,
            "data" => []
          ]);
        }else{
          return response()->json([
            "status" => false,
            "message" => "Password didn't match",
            "data" => []
          ]);
        }
      }else{
        return response()->json([
          "status" => false,
          "message" => "Invalid Email value",
          "data" => []
        ]);
      }
    }

    TEST Login user API using postman

    login
  9. User Profile: In the same file AuthController.php, create a simple method to get the user's details:
  10. public function profile(){
      $userData = auth()->user();
    
      return response()->json([
        "status" => true,
        "message" => "Profile information",
        "data" => $userData,
        "id" => auth()->user()->id
      ]);
    }

    TEST get profile API using postman

    profile
  11. Logout User: In the same file AuthController.php, create a simple method to revoke the token from the user:
  12. public function logout(){
    
      $token = auth()->user()->token();
      $token->revoke();
    
      return response()->json([
        "status" => true,
        "message" => "User Logged out successfully"
      ]);
    }

    TEST logout user API using postman

    logout
© 2017- Pixinvent, Hand-crafted & Made with ❤️