Laravel 11 REST API with Passport Authentication Tutorial
In this post, I will show you how to create REST API with Passport Authentication in laravel 11 application. We will learn from scratch about APIs, REST APIs, and Laravel Passport, and create an example API as well.
What is API?
An API (application programming interface) is simply a way of communication between two or more computer programs.
APIs are also used for web and mobile application development; therefore, building a REST API is very essential for any web and mobile application developer.
What is Laravel Passport?
Laravel Passport is a tool for adding secure authentication to web applications. It helps developers set up authentication using APIs quickly and easily. Passport generates API tokens that users can use to access protected resources. It simplifies tasks like user registration, login, and managing access permissions. With Passport, developers can focus more on building their applications and less on handling authentication details.
We will use Laravel Passport, an authentication system package for developing simple APIs for SPAs (single-page applications) which are commonly built via React JS, Angular, or Vue JS.
In this example, we will install the Laravel 11 application. Then, we will install the Passport composer package for API authentication. After that, we will create register and login APIs for user authentication. Then, we will create a products REST API, and you must authenticate using a user token. So, let's follow the steps below to complete this example step by step:
Step for Laravel 11 Passport REST API Authentication Example
- Step 1: Install Laravel 11
- Step 2: Install Passport
- Step 3: Passport Configuration
- Step 4: Add Product Table and Model
- Step 5: Create API Routes
- Step 6: Create Controller Files
- Step 7: Create Eloquent API Resources
- Run Laravel App
Follow the below few steps to create a restful API example in the laravel 11 app.
Step 1: Install Laravel 11
This step is not required; however, if you have not created the Laravel app, then you may go ahead and execute the below command:
composer create-project laravel/laravel example-app
Step 2: Install Passport
In Laravel 11, by default, we don't have an api.php route file. So, you just need to run the following command to install passport with api.php file.
php artisan install:api --passport
Step 3: Passport Configuration
In this step, we have to configure three places: the model, the service provider, and the auth config file. So, you just need to follow the changes in those files.
In the model, we added the HasApiTokens class of Passport.
In the auth.php file, we added API auth configuration.
app/Models/User.php
<?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 HasFactory, Notifiable, HasApiTokens;
/**
* The attributes that are mass assignable.
*
* @var array
*/
protected $fillable = [
'name',
'email',
'password',
];
/**
* The attributes that should be hidden for serialization.
*
* @var array
*/
protected $hidden = [
'password',
'remember_token',
];
/**
* Get the attributes that should be cast.
*
* @return array
*/
protected function casts(): array
{
return [
'email_verified_at' => 'datetime',
'password' => 'hashed',
];
}
}
config/auth.php
<?php
return [
.....
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],
'api' => [
'driver' => 'passport',
'provider' => 'users',
],
],
.....
]
Step 4: Add Product Table and Model
Next, we need to create a migration for the posts table using the Laravel 11 php artisan command, so first, fire the command below:
php artisan make:migration create_products_table
After this command, you will find one file in the following path database/migrations, and you have to put the below code in your migration file to create the products table.
<?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');
}
};
After create migration we need to run above migration by following command:
php artisan migrate
After creating the "products" table, you should create a Product model for products. So, first create a file in this path app/Models/Product.php and put the following content in it:
app/Models/Product.php
<?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'
];
}
Step 5: Create API Routes
In this step, we will create API routes. Laravel provides the api.php file for writing web service routes. So, let's add a new route to that file.
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;
Route::post('register', [RegisterController::class, 'register']);
Route::post('login', [RegisterController::class, 'login']);
Route::middleware('auth:api')->group( function () {
Route::resource('products', ProductController::class);
});
Step 6: Create Controller Files
In the next step, we've created a new controller called BaseController, ProductController, and RegisterController. I created a new folder named "API" in the Controllers folder because we'll have separate controllers for APIs. So, let's create both controllers:
app/Http/Controllers/API/BaseController.php
<?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')->accessToken;
$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')-> accessToken;
$success['name'] = $user->name;
return $this->sendResponse($success, 'User login successfully.');
}
else{
return $this->sendError('Unauthorised.', ['error'=>'Unauthorised']);
}
}
}
app/Http/Controllers/API/ProductController.php
<?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
This is a very important step in creating a REST API in Laravel 11. You can use Eloquent API resources with the API. It will help you to maintain the same response layout of your model object. We used it in the ProductController file. Now, we have to create it using the following command:
php artisan make:resource ProductResource
Now there created new file with new folder on following path:
app/Http/Resources/ProductResource.php
<?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:
All the required steps have been done, now you have to type the given below command and hit enter to run the Laravel app:
php artisan serve
make sure in details api we will use following headers as listed bellow:
'headers' => [
'Accept' => 'application/json',
'Authorization' => 'Bearer '.$accessToken,
]
Here is Routes URL with Verb:
Now simply you can run above listed url like as bellow screen shot:
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}
You can download code from git: Download Code from Github
I hope it can help you...
Hardik Savani
I'm a full-stack developer, entrepreneur and owner of ItSolutionstuff.com. I live in India and I love to write tutorials and tips that can help to other artisan. I am a big fan of PHP, Laravel, Angular, Vue, Node, Javascript, JQuery, Codeigniter and Bootstrap from the early stage. I believe in Hardworking and Consistency.
We are Recommending you
- Laravel 11 Many to Many Eloquent Relationship Tutorial
- Laravel 11 Has Many Through Relationship Example
- Laravel 11 One to One Relationship Example
- How to Generate QR Code in Laravel 11?
- Laravel 11 Resize Image Before Upload Example
- Laravel 11 Multi Auth: Create Multiple Authentication in Laravel 11
- How to Get Last Executed Query in Laravel 11?
- Laravel 11 Flash Message Example Tutorial
- Laravel 11 Ajax CRUD Operation Tutorial Example
- Laravel 11 Cron Job Task Scheduling Tutorial
- Laravel 11 Yajra Datatables Example Tutorial
- Laravel 11 REST API Authentication using Sanctum Tutorial
- Laravel 11 Ajax Form Validation Example Tutorial
- Laravel 11 CRUD Application Example Tutorial