Build REST API with Laravel Passport
REST APIs are the backbone of modern web and mobile applications. While building a RESTful API with Laravel is straightforward, securing it is equally crucial. Laravel Passport offers a full OAuth2 server implementation for your Laravel application, enabling robust and standard methods of API authentication. In this article, we'll guide you through building a REST API with Passport, from installation to securing your endpoints.
Table of Contents
- Why Use Laravel Passport?
- Setting Up Laravel Passport
- Configuring Authentication Guards
- Building a Simple REST API
- Protecting Routes with Passport
- Testing the API
- Conclusion
Why Use Laravel Passport?
Passport provides a complete OAuth2 server for your app. Major reasons to choose Passport include:
- OAuth2 Compliance: Standard and secure for third-party integrations.
- First-party SPA Support: Easily issue tokens for your own frontend clients.
- Refresh Tokens: Out-of-the-box support for token renewal.
- User Scopes: Fine-grained access control by defining user abilities.
Setting Up Laravel Passport
Let's get started securing your API:
Prerequisites
- Laravel 10+ installed
- Composer
- A configured database
1. Install Passport
composer require laravel/passport
2. Run Migrations
Passport requires several tables, like oauth_clients
, oauth_access_tokens
, etc.
php artisan migrate
3. Install Passport Assets
This command generates the encryption keys and clients required for issuing tokens.
php artisan passport:install
You’ll see something like:
Personal access client created successfully
Client ID: 1
Client secret: [secret]
Keep these credentials safe!
4. Add Passport Traits to User Model
Open app/Models/User.php
:
namespace App\Models;
use Laravel\Passport\HasApiTokens;
class User extends Authenticatable
{
use HasApiTokens, Notifiable;
// ...
}
5. Register Passport Service Provider
Edit config/app.php
(for Laravel < 5.5) or confirm Passport's service provider is auto-discovered.
6. Configure Auth Guard
In config/auth.php
, set the API driver to passport
:
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],
'api' => [
'driver' => 'passport',
'provider' => 'users',
],
],
Configuring Authentication Guards
Passport works with the api
guard by default. You can use Passport for other guards if needed, but sticking to the default is advisable for most REST APIs.
Building a Simple REST API
Let’s create a simple "Post" resource with authentication:
1. Create a Model, Migration, and Controller
php artisan make:model Post -mcr
Add fields to database/migrations/xxxx_xx_xx_create_posts_table.php
:
public function up()
{
Schema::create('posts', function (Blueprint $table) {
$table->id();
$table->foreignId('user_id')->constrained()->onDelete('cascade');
$table->string('title');
$table->text('body');
$table->timestamps();
});
}
Run migration:
php artisan migrate
2. Define API Routes
In routes/api.php
:
Route::post('register', [AuthController::class, 'register']);
Route::post('login', [AuthController::class, 'login']);
Route::middleware('auth:api')->group(function() {
Route::apiResource('posts', PostController::class);
Route::post('logout', [AuthController::class, 'logout']);
});
3. Create an Auth Controller
Generate controller:
php artisan make:controller AuthController
Implement registration, login, and logout methods in app/Http/Controllers/AuthController.php
:
use Illuminate\Http\Request;
use App\Models\User;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Hash;
use Illuminate\Validation\ValidationException;
public function register(Request $request)
{
$validated = $request->validate([
'name' => 'required|string|max:255',
'email' => 'required|email|unique:users,email',
'password' => 'required|string|min:8|confirmed',
]);
$user = User::create([
'name' => $validated['name'],
'email' => $validated['email'],
'password' => bcrypt($validated['password']),
]);
$token = $user->createToken('Personal Access Token')->accessToken;
return response()->json([
'user' => $user,
'access_token' => $token,
'token_type' => 'Bearer',
]);
}
public function login(Request $request)
{
$credentials = $request->validate([
'email' => 'required|email',
'password' => 'required',
]);
if (!Auth::attempt($credentials)) {
throw ValidationException::withMessages([
'email' => ['The provided credentials are incorrect.'],
]);
}
$user = Auth::user();
$token = $user->createToken('Personal Access Token')->accessToken;
return response()->json([
'user' => $user,
'access_token' => $token,
'token_type' => 'Bearer',
]);
}
public function logout(Request $request)
{
$request->user()->token()->revoke();
return response()->json(['message' => 'Successfully logged out']);
}
4. Implement Resource Controller
Edit app/Http/Controllers/PostController.php
and implement standard CRUD functions (index, store, show, update, destroy).
Example - restrict posts to authenticated users:
public function store(Request $request)
{
$validated = $request->validate([
'title' => 'required',
'body' => 'required',
]);
$post = $request->user()->posts()->create($validated);
return response()->json($post, 201);
}
Protecting Routes with Passport
The auth:api
middleware restricts routes to clients who provide valid Bearer tokens.
Example request header:
Authorization: Bearer {access_token}
Attempting to access protected endpoints without a valid token returns a 401 Unauthorized error.
Testing the API
You can use tools like Postman or curl to interact with your API:
1. Register
curl -X POST http://localhost/api/register \
-H "Content-Type: application/json" \
-d '{"name":"Jane Doe", "email":"jane@doe.com", "password":"secret123", "password_confirmation":"secret123"}'
2. Login
curl -X POST http://localhost/api/login \
-H "Content-Type: application/json" \
-d '{"email":"jane@doe.com", "password":"secret123"}'
Save the access_token
from the response.
3. Call Protected Route
curl -X GET http://localhost/api/posts \
-H "Authorization: Bearer {access_token}"
Conclusion
Laravel Passport makes implementing OAuth2 authentication in your REST API effortless, bringing robust security features and token management. Passport's out-of-the-box functionality saves hours of manual configuration while staying aligned with industry best practices.
Now your Laravel API is ready to securely interact with external applications and SPAs!
References:
Happy Coding!