REST Api Development in Laravel 8 with Passport

Share this Article
Reading Time: 14 minutes
2,041 Views

Inside this article we will one more important concept of laravel i.e REST api development in laravel 8 with Passport. This will be step by step guide to create restful services from scratch.

We will create a secure set of rest apis using laravel. Passport is a laravel composer package.

What we will do in this article –

  • User Register API
  • Login API
  • Profile API
  • Logout API
  • Create Blog
  • List Blog
  • Single Blog details
  • Update Blog
  • Delete Blog

Above are the apis, we will create using passport authentication. This will be very interesting to learn.

  • To Learn API development in Laravel 8 Using JWT Authentication, Click here.
  • REST APIs in Laravel 8 Using Sanctum Authentication, Click here.

Let’s get started.


Installation of Laravel Application

Laravel Installation can be done in two ways.

  • Laravel Installer
  • By using composer

Laravel Installer

To install Laravel via Laravel installer, we need to install it’s installer first. We need to make use of composer for that.

$ composer global require laravel/installer

This command will install laravel installer at system. This installation is at global scope, so you type command from any directory at terminal. To verify type the given command –

$ laravel

This command will open a command palette of Laravel Installer.

To create ad install laravel project in system,

$ laravel new blog

With the name of blog a laravel project will be created at your specified path.

By using composer

Alternatively, we can also install Laravel by Composer command create-project.

If your system doesn’t has composer Installed, Learn Composer Installation Steps.

Here is the complete command to create a laravel project-

$ composer create-project --prefer-dist laravel/laravel blog

After following these steps we can install a Laravel application into system.

To start the development server of Laravel –

$ php artisan serve

This command outputs –

Starting Laravel development server: http://127.0.0.1:8000

Assuming laravel already installed at system.


Create Database & Connect

To create a database, either we can create via Manual tool of PhpMyadmin or by means of a mysql command.

CREATE DATABASE laravel_app;

To connect database with application, Open .env file from application root. Search for DB_ and update your details.

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=laravel_app
DB_USERNAME=root
DB_PASSWORD=root

Install And Configure Laravel Passport

Laravel Passport package provides a full 0Auth2 server implementation for Laravel applications. By using it, we can easily generate a personal access token to uniquely identify a currently authenticated user. This token will then be attached to every request allowing each user access to protected routes. 

Open project into terminal and run this command.

$ composer require laravel/passport

After installation of package, it will create a migration file which provides a scheme to store clients and access tokens

Next, we need to migrate file.

$ php artisan migrate

To create the encryption keys which needed to generate secured access tokens, run this given command

$ php artisan passport:install

Update User Model

When we install laravel setup, by default we will get a model User.php at /app/Models.

Open User.php and update by this code.

<?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; // Add this line

class User extends Authenticatable
{
    use HasFactory, Notifiable, HasApiTokens;  // Add this HasApiTokens

    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $fillable = [
        'name',
        'email',
        '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',
    ];
}

Update AuthServiceProvider File

Open AuthServiceProvider.php from /app/Providers folder and update by this piece of code.

<?php

namespace App\Providers;

use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;
use Illuminate\Support\Facades\Gate;
use Laravel\Passport\Passport; // Add this

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();

        Passport::routes(); // Add this
    }
}

After registering Passport::routes(), Laravel Passport is almost ready to handle all authentication and authorization processes within laravel application.


Update auth Config File

Open auth.php from /config folder. Search for guards into that file and update it.

//...

'guards' => [
        
       //...
  
        'api' => [
            'driver' => 'passport', // set this to passport
            'provider' => 'users',
            'hash' => false,
        ],
    ],

//...

Create Model & Migration For Blog

Open project into terminal and run this artisan command.

$ php artisan make:model Blog -m

-m to create migration file as well.

Above command will generate two files. One is Model and second is migration file.

Model – Blog.php at /app/Models

Migration – 2021_03_20_040948_create_blogs_table.php at /Database/migrations

Open Blog.php and write this code into it.

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class Blog extends Model
{
    use HasFactory;

    public $timestamps = false;

    protected $fillable = [
        'user_id', 'title', 'description'
    ];
}

Open Migration file 2021_03_20_040948_create_blogs_table.php and write this code.

<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class CreateBlogsTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('blogs', function (Blueprint $table) {
            $table->id();
            $table->integer("user_id")->unsigned();
            $table->string("title", 80);
            $table->text("description");
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('blogs');
    }
}

Migration Migration

Back to terminal and run this command to create blogs table.

$ php artisan migrate

Create Controllers

Back to terminal and run these artisan commands to create.

Authentication Controller

$ php artisan make:controller API/AuthController

This command will create a file AuthController.php at /app/Http/Controllers/API. API is the folder will be created.

Blog Controller

$ php artisan make:controller API/BlogController --api --model=Blog

This command will create a file BlogController.php file at /app/Http/Controllers/API folder.

Open AuthController.php and write this code.

<?php

namespace App\Http\Controllers\API;

use App\Http\Controllers\Controller;
use App\Models\User;
use Illuminate\Http\Request;

class AuthController extends Controller
{
    public function register(Request $request)
    {
        $validatedData = $request->validate([
            'name' => 'required|max:55',
            'email' => 'email|required|unique:users',
            'password' => 'required|confirmed'
        ]);

        $validatedData['password'] = bcrypt($request->password);

        $user = User::create($validatedData);

        $accessToken = $user->createToken('authToken')->accessToken;

        return response([ 'user' => $user, 'access_token' => $accessToken]);
    }

    public function login(Request $request)
    {
        $loginData = $request->validate([
            'email' => 'email|required',
            'password' => 'required'
        ]);

        if (!auth()->attempt($loginData)) {
            return response(['message' => 'Invalid Credentials']);
        }

        $accessToken = auth()->user()->createToken('authToken')->accessToken;

        return response(['user' => auth()->user(), 'access_token' => $accessToken]);
    }
  
    public function profile()
    {
        $user_data = auth()->user();

        return response()->json([
            "status" => true,
            "message" => "User data",
            "data" => $user_data
        ]);
    }
  
    public function logout(Request $request)
    {
        // get token value
        $token = $request->user()->token();

        // revoke this token value
        $token->revoke();

        return response()->json([
            "status" => true,
            "message" => "User logged out successfully"
        ]);
    }
}

Open BlogController.php and write this code.

<?php

namespace App\Http\Controllers\API;

use App\Models\Blog;
use App\Http\Controllers\Controller;
use App\Http\Resources\BlogResource;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Validator;

class BlogController extends Controller
{
    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function index()
    {
        $blogs = Blog::all();
        return response([ 'blogs' => BlogResource::collection($blogs), 'message' => 'Retrieved successfully'], 200);
    }

    /**
     * Store a newly created resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function store(Request $request)
    {
        $data = $request->all();

        $validator = Validator::make($data, [
            'title' => 'required|max:80',
            'description' => 'required'
        ]);

        if($validator->fails()){
            return response(['error' => $validator->errors(), 'Validation Error']);
        }

        $user_id = auth()->user()->id;

        $data["user_id"] = $user_id;

        $blog = Blog::create($data);

        return response([ 'blog' => new BlogResource($blog), 'message' => 'Created successfully'], 200);
    }

    /**
     * Display the specified resource.
     *
     * @param  \App\Models\Blog $blog
     * @return \Illuminate\Http\Response
     */
    public function show(Blog $blog)
    {
        return response([ 'blog' => new BlogResource($blog), 'message' => 'Retrieved successfully'], 200);

    }

    /**
     * Update the specified resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \App\Models\Blog $blog
     * @return \Illuminate\Http\Response
     */
    public function update(Request $request, Blog $blog)
    {

        $blog->update($request->all());

        return response([ 'blog' => new BlogResource($blog), 'message' => 'Retrieved successfully'], 200);
    }

    /**
     * Remove the specified resource from storage.
     *
     * @param \App\Models\Blog $blog
     * @return \Illuminate\Http\Response
     * @throws \Exception
     */
    public function destroy(Blog $blog)
    {
        $blog->delete();

        return response(['message' => 'Deleted']);
    }
}

Create Resource

Laravel Eloquent resources allow you to convert your models and collections into JSON format. 

Open terminal and write this command

$ php artisan make:resource BlogResource

It will create file BlogResource.php at location /app/Http/Resources.

Open BlogResource.php and write this code.

<?php

namespace App\Http\Resources;

use Illuminate\Http\Resources\Json\JsonResource;

class BlogResource extends JsonResource
{
    /**
     * Transform the resource into an array.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return array
     */
    public function toArray($request)
    {
        return parent::toArray($request);
    }
}

Create API Routes

Open api.php from /routes folder. Add these routes into it.

// At header
use App\Http\Controllers\API\AuthController;
use App\Http\Controllers\API\BlogController;

Route::post('register', [AuthController::class, "register"]);
Route::post('login', [AuthController::class, "login"]);

Route::group(["middleware" => ["auth:api"]], function(){

    Route::get("profile", [AuthController::class, "profile"]);
    Route::post("logout", [AuthController::class, "logout"]);
});

Route::apiResource('blog', BlogController::class)->middleware('auth:api');

Open terminal and run this artisan command to see all available routes.

$ php artisan route:list

Application Testing

Open project to terminal and type the command to start development server

$ php artisan serve

Register API – http://127.0.0.1:8000/api/register

Method – POST

{
"name": "Sanjay Kumar",
"email": "sanjay@gmail.com",
"password": "12345678",
"password_confirmation": "12345678"
}

Login API – http://127.0.0.1:8000/api/login

Method – POST

{
"email": "sanjay@gmail.com",
"password": "12345678"
}

Profile API – http://127.0.0.1:8000/api/profile

Method: GET

Header

Content-Type:application/json
Accept:application/json

Logout API – http://127.0.0.1:8000/api/logout

Method: POST

Header

Content-Type:application/json
Accept:application/json
Authorization: Bearer <Token>

Create Blog API – http://127.0.0.1:8000/api/blog

Method – POST

Header

Content-Type:application/json
Authorization: Bearer <Token>
Accept:application/json

Body

{
"title": "Blog 1",
"description": "Sample Blog content"
}

List All Blogs API – http://127.0.0.1:8000/api/blog

Method – GET

Header

Content-Type:application/json
Authorization: Bearer <Token>
Accept:application/json

Single Blog Detail API – http://127.0.0.1:8000/api/blog/1

Method – GET

Header

Content-Type:application/json
Authorization: Bearer <Token>
Accept:application/json

Update Blog API – http://127.0.0.1:8000/api/blog/1

Method – PATCH

Header

Content-Type:application/json
Authorization: Bearer <Token>
Accept:application/json

Body

{
"name": "Blog Title updated",
"description": "New content for blog article"
}

Delete Blog API – http://127.0.0.1:8000/api/blog/1

Method – DELETE

Header

Content-Type:application/json
Authorization: Bearer <Token>
Accept:application/json

We hope this article helped you to learn about REST Api Development in Laravel 8 with Passport Tutorial in a very detailed way.

If you liked this article, then please subscribe to our YouTube Channel for PHP & it’s framework, WordPress, Node Js video tutorials. You can also find us on Twitter and Facebook.

Find More on Laravel 8 Articles here