Displaying out JSON data only is not such an API. An API contains the data that synchronizes between the two applications. It connects two applications through an end-point. Basically, it works as an intermediary between the two applications. Every API request will have a response. So, in the overall process the API talks to another application to have the request and the response. You can create Laravel 8 REST API for global and specifically for any website or particular request. This kind of API requests will manage by a token. This token provides the privilege to access the response from the API. Laravel 8 passport authentication provides an authentication token for the API calls. When you will pass this auth token in the header as a bearer then you will have the access to the API call.
Otherwise, you won’t make a call to the API. Laravel 8 passport auth grants a secure and authenticated call for the APIs request. Today, in this Laravel 8 post, you will be learning to create a Laravel 8 REST API using Laravel passport authentication.
Overview of this Application
In this project, we will gonna create the RESTful APIs for the blog application. The basic blog application will have the user and post modules.
In the User module, I will create the following APIs –
- Register
- Login
- Profile
In the Post module, the user can create the posts. But for creating and managing the posts, the user will require the login and the authentication token. This authentication token will be generated by the Passport auth. That means the post created by the user would be related to the same user only. Similarly, the logged user can edit, update, and delete only that post which is created by him/her. The post module will contain the following APIs –
- Create post
- Update post
- Post detail
- Delete post
Prerequisites
Before creating a RESTful API in Laravel 8, you must ensure that your system is ready with the following configurations.
- PHP >= 7.3
- MySQL (version > 5)
- Apache/Nginx Server
- VS Code Editor
- Composer
- Postman
Let’s create a new setup for the Laravel 8 REST API.
Create Project For Laravel 8 REST API with Passport
Create a new project setup in Laravel 8 using the composer.
composer create-project --prefer-dist laravel/laravel rest-api-passport
Here, the project installation has started. It will take a couple of minutes to install the Laravel 8 files in the project directory.
After finishing the project setup, establish the database connection. Hence, create a database and connect it to the Laravel 8 application.
How to Upload Image in CKEditor 5 Using Laravel 8
Establish Database Connection For Passport Auth
For the database, I am using the MySQL. Here, I have created a new database.
CREATE DATABASE laravel8_rest_api
After creating the database, you will require to have a connection with the project. Therefore, navigate the .env file of the project and replace the database credentials as showing below.
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=laravel8_rest_api
DB_USERNAME=root
DB_PASSWORD=root
I have connected the database with this project. Now, our application is ready to co-ordinate with the database. In the next step, we will be installing the package for the Laravel passport.
Install Passport Package in Laravel 8
For using the auth token in the RESTful API, firstly, we will have to install the Laravel 8 passport authentication package. So, let’s install it inside the project.
composer require laravel/passport
Here, the passport package installation has been started.
After the installation of the passport package, we will create the models and migrations.
How to Implement CKEditor 5 in Laravel 8 From Scratch
Create Models and Migrations For Laravel 8 REST API
Here, we have the default model and a migration for the User. Hence, we will require to create a model and migration for the post. So, open the terminal and create it.
php artisan make:model Post --migration
The above command generated two files. One is model and another is the migration.
Now, we will have to specify the fields in both migration files. Currently, we have the users table and posts table migration. So, let’s do it one by one.
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateUsersTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('users', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->string('email')->unique();
$table->string('phone')->nullable();
$table->timestamp('email_verified_at')->nullable();
$table->string('password');
$table->rememberToken();
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('users');
}
}
For the post table migration, here are the specified fields.
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreatePostsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('posts', function (Blueprint $table) {
$table->id();
$table->string('title');
$table->string('description');
$table->bigInteger('user_id')->unsigned();
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('posts');
}
}
Here, we go with the mass assignment of the models.
Laravel 8 Ajax CRUD Application Tutorial For Beginners
Add Fillable Data (Mass Assignment) For Models
In this step, we will require to set the fillable data in the models. Firstly, in the User model, we will need to include a namespace for the passport that is HasAPiTokens. Hence, it will allow the user model to have the authentication token.
I have specified the relationship between the users and the posts table. Hence, this will be a one-to-many relation. This is the powerful feature of using the eloquent.
<?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\Passport\HasApiTokens;
class User extends Authenticatable
{
use HasFactory, Notifiable, HasApiTokens;
/**
* The attributes that are mass assignable.
*
* @var array
*/
protected $fillable = [
'name',
'email',
'phone',
'password',
];
/**
* The attributes that should be hidden for arrays.
*
* @var array
*/
protected $hidden = [
'password',
'remember_token',
];
/**
* The attributes that should be cast to native types.
*
* @var array
*/
protected $casts = [
'email_verified_at' => 'datetime',
];
public function post()
{
return $this->hasMany('App\Models\Post');
}
}
Similarly, passed the fields in the fillable data of the Post model.
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Post extends Model
{
use HasFactory;
protected $fillable = [
"title",
"description",
"user_id"
];
}
In the next step, we will migrate the tables.
php artisan migrate
Here, the migrations has been completed and the couple of tables has been added in the database.
We have the tables ready to proceed with the functionalities. But before moving to the functionalities we have to do one more thing. We have to set the passport auth in the auth service provider.
How to Create and Use Database Seeder in Laravel 8
Add Auth Guard in Auth Service Provider
We have to add the auth guard for the APIs requests. It will enable a kind of filter for every API request. In other words, every API call will go through the passport authentication.
Navigate the app/Providers/AuthServiceProvider.php file. Then firstly, add a namespace.
use Laravel\Passport\Passport;
Then in the boot() function add the passport route.
Passport::routes();
Here, after adding the above codes, it will look like this.
<?php
namespace App\Providers;
use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;
use Illuminate\Support\Facades\Gate;
use Laravel\Passport\Passport;
class AuthServiceProvider extends ServiceProvider
{
/**
* The policy mappings for the application.
*
* @var array
*/
protected $policies = [
// 'App\Models\Model' => 'App\Policies\ModelPolicy',
];
/**
* Register any authentication / authorization services.
*
* @return void
*/
public function boot()
{
$this->registerPolicies();
// Add passport routes
Passport::routes();
}
}
In the next step, we will be have to set the passport in the guards. So, you can find out the config/auth.php file.
Here, just change the below driver for the API. Actually, we are using the Passport so replace the API driver with the passport.
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],
'api' => [
'driver' => 'passport',
'provider' => 'users',
'hash' => false,
],
],
Now, after setting up the guards we will have to install the auth key.
How to Create Pagination in Laravel 8 with Eloquent
Install Passport Auth Key
In this step, we will be adding the passport auth to the OAuth tables. It will install an auth key for validating the users. Laravel passport provides the OAuthClients and OAuthPersonalAccessClient for the encryption key. This encryption key will be used to validate the API request of the authenticated user.
php artisan passport:install
Here, the above command will generate the Client Id and the Client secret in the oauth_clients table.
Create Controllers For Laravel 8 Passport Authentication
For creating Laravel 8 REST API with passport, we will require creating controllers. As per the model, we have to create two controllers.
The first controller will be for the User.
php artisan make:controller UserController
The second controller will be for the Post.
php artisan make:controller PostController --resource
Therefore, I have created these controllers. In the Post controller, you can add resource for performing the create, store, edit, update and delete. It is up to you.
After creating these controllers. Let’s add the functionalities one by one.
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Validator;
use App\Models\User;
class UserController extends Controller
{
private $sucess_status = 200;
// Create User
public function registerUser(Request $request) {
$validator = Validator::make($request->all(),
[
'name' => 'required',
'email' => 'required|email',
'phone' => 'required|numeric',
'password' => 'required|alpha_num|min:5'
]
);
if($validator->fails()) {
return response()->json(["validation_errors" => $validator->errors()]);
}
$inputs = $request->all();
$inputs['password'] = bcrypt($inputs['password']);
$user = User::create($inputs);
if(!is_null($user)) {
return response()->json(["status" => $this->sucess_status, "success" => true, "data" => $user]);
}
else {
return response()->json(["status" => "failed", "success" => false, "message" => "Whoops! user not created. please try again."]);
}
}
// User Login
public function loginUser(Request $request) {
// validation
$validator = Validator::make($request->all(),
[
'email' => 'required|email',
'password' => 'required|alpha_num|min:5'
]
);
if($validator->fails()) {
return response()->json(["validation_errors" => $validator->errors()]);
}
if(Auth::attempt(['email' => $request->email, 'password' => $request->password])){
$user = Auth::user();
$token = $user->createToken('token')->accessToken;
return response()->json(["status" => $this->sucess_status, "success" => true, "login" => true, "token" => $token, "data" => $user]);
}
else {
return response()->json(["status" => "failed", "success" => false, "message" => "Whoops! invalid email or password"]);
}
}
// User Detail
public function userDetail() {
$user = Auth::user();
if(!is_null($user)) {
return response()->json(["status" => $this->sucess_status, "success" => true, "user" => $user]);
}
else {
return response()->json(["status" => "failed", "success" => false, "message" => "Whoops! no user found"]);
}
}
}
How to Use Guzzle Http in Laravel 8 For Request Handling
Add Routes of UserController
So, we will have to add the routes in the routes/api.php. Firstly, we will add the routes for the UserController functions.
// User Controller
Route::post("register", [UserController::class, "registerUser"]);
Route::post("login", [UserController::class, "loginUser"]);
Route::middleware('auth:api')->group( function () {
Route::get("user", [UserController::class, "userDetail"]);
});
In the above snippet (UserController.php), I have added the functions to register users, login users, and user detail.
Register User End Point
For testing the APIs endpoint, I will use the Postman tool. Here, this is the endpoint for the user register.
http://localhost:8000/api/register
Request Type: POST
Data: Body->form-data
I have used the validation for the user register. When the required fields are empty then it will show the validation errors as showing below.
So, enter the required fields and try hitting the API. The required fields are name, email, phone, and password.
It will return the success response with data.
So, here, user registration has completed. Now, let’s hit the login endpoint.
User Login End Point
For the login, this will be the endpoint –
http://localhost:8000/api/login
Request Type: POST
Data: Body->form-data
Here, the required fields are email and password. We will login with email and password. So, here the validation errors will be showing if required fields will blank.
After giving the email and password, hit the send button.
In the success response, you will get the auth token as showing below.
So, here we got the authentication token after the successful login. Now, the rest endpoints will be called using this token.
User Detail End Point with Auth Token
Similarly, we have an endpoint for the user profile. But this endpoint will require the auth token because the route is placed between the middleware of auth:api.
http://localhost:8000/api/user
Request Type: GET
Headers: Authorization:Bearer AuthToken
Here, I have passed the authentication with bearer token in the headers.
Now, hit the API for the response. As a result, you can see we got the user data.
That’s it for the user controller. Now, we will work on the PostController.php.
How to Implement Yajra DataTables in Laravel 8
PostController Functionalities
Now, add the below codes in the post controller. Here, I have added the functionalities in the resource methods.
<?php
namespace App\Http\Controllers;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Validator;
use App\Models\Post;
use Illuminate\Http\Request;
class PostController extends Controller
{
public $success_status = 200;
/**
* Display a listing of the resource.
*
* @return \Illuminate\Http\Response
*/
public function index()
{
$posts = array();
$user = Auth::user();
if(!is_null($user)) {
$posts = Post::where("user_id", $user->id)->get();
if(count($posts) > 0) {
return response()->json(["status" => $this->success_status, "success" => true, "count" => count($posts), "data" => $posts]);
}
else {
return response()->json(["status" => "failed", "success" => false, "message" => "Whoops! no post found"]);
}
}
else {
return response()->json(["status" => "failed", "message" => "Whoops! invalid auth token"]);
}
}
/**
* Store a newly created resource in storage.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function store(Request $request)
{
$user = Auth::user();
if(!is_null($user)) {
$validator = Validator::make($request->all(),
[
"title" => "required",
"description" => "required",
]
);
if($validator->fails()) {
return response()->json(["validation_errors" => $validator->errors()]);
}
$post_array = array(
"title" => $request->title,
"description" => $request->description,
"user_id" => $user->id
);
$post = Post::create($post_array);
if(!is_null($post)) {
return response()->json(["status" => $this->success_status, "success" => true, "data" => $post]);
}
else {
return response()->json(["status" => "failed", "success" => false, "message" => "Whoops! post not created."]);
}
}
else {
return response()->json(["status" => "failed", "message" => "Whoops! invalid auth token"]);
}
}
/**
* Display the specified resource.
*
* @param int $id
* @return \Illuminate\Http\Response
*/
public function show($id)
{
$user = Auth::user();
if(!is_null($user)) {
$post = Post::where("id", $id)->where("user_id", $user->id)->first();
if(!is_null($post)) {
return response()->json(["status" => $this->success_status, "success" => true, "data" => $post]);
}
else {
return response()->json(["status" => "failed", "success" => false, "message" => "Whoops! no post found"]);
}
}
else {
return response()->json(["status" => "failed", "message" => "Whoops! invalid auth token"]);
}
}
/**
* Update the specified resource in storage.
*
* @param \Illuminate\Http\Request $request
* @param int $id
* @return \Illuminate\Http\Response
*/
public function update(Request $request, Post $post)
{
$input = $request->all();
$user = Auth::user();
if(!is_null($user)) {
// validation
$validator = Validator::make($request->all(), [
"title" => "required",
"description" => "required",
]);
if($validator->fails()) {
return response()->json(["status" => "failed", "validation_errors" => $validator->errors()]);
}
// update post
$update = $post->update($request->all());
return response()->json(["status" => $this->success_status, "success" => true, "data" => $post]);
}
else {
return response()->json(["status" => "failed", "message" => "Whoops! invalid auth token"]);
}
}
/**
* Remove the specified resource from storage.
*
* @param int $id
* @return \Illuminate\Http\Response
*/
public function destroy(Post $post)
{
if(!is_null($post)) {
$delete = $post->delete();
if($delete == true) {
return response()->json(["status" => $this->success_status, "success" => true, "message" => "Success! post deleted"]);
}
else {
return response()->json(["status" => "failed", "success" => false, "message" => "Alert! post not deleted"]);
}
}
else {
return response()->json(["status" => "failed", "success" => false, "message" => "Alert! post not found"]);
}
}
}
Now, for the above functions, we will have to add the routes.
How to Send Emails Using Twilio Sendgrid in Laravel 8
Add Routes for PostController
Here, for the PostController, I will add resource route. So, every functions will call with the resource route. But, this time, the route will be added in the middleware.
<?php
use App\Http\Controllers\PostController;
use App\Http\Controllers\UserController;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;
Route::middleware('auth:api')->get('/user', function (Request $request) {
return $request->user();
});
// User Controller
Route::post("register", [UserController::class, "registerUser"]);
Route::post("login", [UserController::class, "loginUser"]);
Route::middleware('auth:api')->group( function () {
Route::get("user", [UserController::class, "userDetail"]);
Route::resource('posts', PostController::class);
});
After adding the routes, let’s check the endpoints.
POST Request For Creating Post
For creating the new post, here we have the endpoint. For the resource route of PostController, we will have to pass the auth token in the header as a bearer. This is the actual mean of Laravel 8 REST API with passport authentication.
EndPoint: http://localhost:8000/api/posts
Request Type: POST
data: Body->form-data
Headers
Authorization: Bearer AuthToken
As, you can see here, I have passed the Authorization with value of Bearer AuthToken in the headers.
I have set the validation for some fields like title and description of the post. So, when I triggered the API without any inputs then it shown me the below validation errors message.
Now, I have entered the required values in the key.
After the API call, I go the below response. It means the post has created.
GET Request For Fetching Posts
After creating the posts, we will fetch all the posts created by the logged-in user. So, similarly, it will require the authorization token in the headers. Then through the token, we will get the logged user and will fetch all the posts created by the same user.
EndPoint: http://localhost:8000/api/posts
Request Type: GET
Authorization: Bearer AuthToken
Now, hit the API, and you will have the response as showing below.
Similarly, if we want to fetch a single post then, we will have to use the GET request with the post id (primary field).
GET Request For Post Detail
For the post detail, we have to use the GET request and the primary field as well. Here, the post id is a primary field. So, here, this will be the endpoint.
EndPoint: http://localhost:8000/api/posts/{post_id}
Request Type: GET
Headers
Authorization: Bearer AuthToken
After hitting the API, you will get the below response.
In the next step, we will update the post.
PUT Request to Update Post
For updating the post, we will have the use the PUT request. The PUT request take the post id (primary field) and the parameters paired with key and values.
EndPoint: http://localhost:8000/api/posts/{post_id}/?{field1=value1&field2=value2}
Request Type: PUT
Headers
Authorization: Bearer AuthToken
So, after hitting the API, we have the below response. Here, the post is updated.
At last, we have to perform the delete operation.
DELETE Request to Delete a Post
For deleting a post we will use the DELETE request. Similarly, we will have to pass the auth token in the headers and the primary field (post id) in the parameter.
EndPoint: http://localhost:8000/api/posts/{post_id}
Request Type: DELETE
Headers
Authorization: Bearer AuthToken
So, after hitting the API, you will have the below response.
Conclusion
We have create Laravel 8 REST API with Passport Authentication. Here, we have installed the passport auth key that provides the OAuth client and personal access token. This generates the Client Id and the Client Secret to validate the authentication. Laravel 8 passport authentication provides the authenticated API call using auth token. You won’t be able to make an API call without authorization if route is placed inside the middleware of auth api. So, I hope, this post will guide you in the simplify way to create RESTful APIs in Laravel 8.
Leave a Reply