Today we are going to build a REST API using Laravel and Laravel Passport. To implement API, we use php framework Laravel , Laravel Passport and we use MYSQL to store our data.

Prerequisites

  • Laravel
  • To Continue with this tutorial, you should have installed Laravel 8 in your pc. If you are still not installed Laravel in your machine you can configure it from here.
  • Postman
  • To test our API endpoints, you need a API Testing application like Postman. You can download Postman from here.

    Setting up the Project

    First you need to create a new laravel project by running below command in your terminal
    1
    composer create-project laravel/laravel laravel-passport-auth --prefer-dist

    Then navigate to your project directory by using below command in your terminal

    1
    cd laravel-passport-auth

    Setting up Database

    To setup up Database for our project, open the application using your favourite text editor and and then navigate to .env file in it and then change below section acording to your Database settings:

    1
    2
    3
    4
    5
    6
    DB_CONNECTION=mysql
    DB_HOST=127.0.0.1
    DB_PORT=3306
    DB_DATABASE=laravel-passport-auth
    DB_USERNAME=root
    DB_PASSWORD=

    Install Passport Package

    Now we need to o install the passport package through Composer package manager.
    1
    composer require laravel/passport

    Now we need to run the default migration to create a new tables in the MySQL database.

    1
    php artisan migrate

    Next, to generate token keys for securing our application.

    1
    php artisan passport:install

    Configure Passport Module

    To configure the Passport package in our Laravel application, open app/Models/User.php file and include HasApiTokens trait inside the User model, as mentioned below.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    <?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',
    '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',
    ];
    }

    Now open app/Providers/AuthServiceProvider.php file and paste below code:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    <?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();
    Passport::routes();
    }
    }

    Then you shoul register register the PassportServiceProvider class in providers array inside the config/app.php file:

    1
    2
    3
    4
    5
    6
    7
    'providers' => [
    ...
    ...
    ...
    Laravel\Passport\PassportServiceProvider::class,

    ],

    Finally we need to configure the driver for the Passport. To do it get inside the config/auth.php file and make the changes as shown below.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    <?php
    return [
    ....
    ....

    'guards' => [
    'web' => [
    'driver' => 'session',
    'provider' => 'users',
    ],

    'api' => [
    'driver' => 'passport',
    'provider' => 'users',
    ],
    ],

    ....
    ....
    ]

    Create Posts Model & Run Migration

    To make the connection between the client and the server, we we require to create the Post model by running below command:
    1
    php artisan make:model Post -m

    After executing the above command, navigate to database/migrations/timestamp_create_posts_table and change it shown as below:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    <?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->increments('id');
    $table->unsignedBigInteger('user_id');
    $table->text('title');
    $table->longText('description');
    $table->timestamps();

    $table->foreign('user_id')->references('id')->on('users');
    });
    }

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

    Then navigate to app/Models/Post.php file and register the following values inside $fillablearray.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    <?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'
    ];
    }

    Then, run the migration by using the below command:

    1
    php artisan migrate

    Create a New Controller

    Then we need to create a new controller in our laravel app to create a login and registration REST API.
    1
    php artisan make:controller PassportAuthController

    Now you need to replace PassportAuthController.php by inserting below code:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    <?php

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

    class PassportAuthController extends Controller
    {
    /**
    * Registration
    */
    public function register(Request $request)
    {
    $this->validate($request, [
    'name' => 'required|min:4',
    'email' => 'required|email',
    'password' => 'required|min:8',
    ]);

    $user = User::create([
    'name' => $request->name,
    'email' => $request->email,
    'password' => bcrypt($request->password)
    ]);

    $token = $user->createToken('LaravelAuthApp')->accessToken;

    return response()->json(['token' => $token], 200);
    }

    /**
    * Login
    */
    public function login(Request $request)
    {
    $data = [
    'email' => $request->email,
    'password' => $request->password
    ];

    if (auth()->attempt($data)) {
    $token = auth()->user()->createToken('LaravelAuthApp')->accessToken;
    return response()->json(['token' => $token], 200);
    } else {
    return response()->json(['error' => 'Unauthorised'], 401);
    }
    }
    }

    Now we need to establish our connection between Post and User model. Change app/Models/User.php file.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    <?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',
    '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 posts()
    {
    return $this->hasMany(Post::class);
    }
    }

    Then create Post Controller by running below command:

    1
    php artisan make:controller PostController

    Then add following code in to PostController.php

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    <?php

    namespace App\Http\Controllers;
    use Illuminate\Http\Request;
    use App\Models\Post;

    class PostController extends Controller
    {
    public function index()
    {
    $posts = auth()->user()->posts;

    return response()->json([
    'success' => true,
    'data' => $posts
    ]);
    }

    public function show($id)
    {
    $post = auth()->user()->posts()->find($id);

    if (!$post) {
    return response()->json([
    'success' => false,
    'message' => 'Post not found '
    ], 400);
    }

    return response()->json([
    'success' => true,
    'data' => $post->toArray()
    ], 400);
    }

    public function store(Request $request)
    {
    $this->validate($request, [
    'title' => 'required',
    'description' => 'required'
    ]);

    $post = new Post();
    $post->title = $request->title;
    $post->description = $request->description;

    if (auth()->user()->posts()->save($post))
    return response()->json([
    'success' => true,
    'data' => $post->toArray()
    ]);
    else
    return response()->json([
    'success' => false,
    'message' => 'Post not added'
    ], 500);
    }

    public function update(Request $request, $id)
    {
    $post = auth()->user()->posts()->find($id);

    if (!$post) {
    return response()->json([
    'success' => false,
    'message' => 'Post not found'
    ], 400);
    }

    $updated = $post->fill($request->all())->save();

    if ($updated)
    return response()->json([
    'success' => true
    ]);
    else
    return response()->json([
    'success' => false,
    'message' => 'Post can not be updated'
    ], 500);
    }

    public function destroy($id)
    {
    $post = auth()->user()->posts()->find($id);

    if (!$post) {
    return response()->json([
    'success' => false,
    'message' => 'Post not found'
    ], 400);
    }

    if ($post->delete()) {
    return response()->json([
    'success' => true
    ]);
    } else {
    return response()->json([
    'success' => false,
    'message' => 'Post can not be deleted'
    ], 500);
    }
    }
    }

    Define API Routes

    Go to your routes/api.php file and place below code in it:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    <?php

    use Illuminate\Http\Request;
    use Illuminate\Support\Facades\Route;
    use App\Http\Controllers\PassportAuthController;
    use App\Http\Controllers\PostController;

    /*
    |--------------------------------------------------------------------------
    | API Routes
    |--------------------------------------------------------------------------
    |
    | Here is where you can register API routes for your application. These
    | routes are loaded by the RouteServiceProvider within a group which
    | is assigned the "api" middleware group. Enjoy building your API!
    |
    */

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

    Route::middleware('auth:api')->group(function () {
    Route::resource('posts', PostController::class);
    });

    Run our application

    Now we have already finished with our API creation. Before testing our API in Postman, you need to run your application using below command:

    1
    php artisan serve

    Testing APIs

    To test our API endpoints, we need to use Postman.

    Conclusion

    In this tutorial, we implemented Laravel REST API with Passport Authentication. If you have any issue regarding this tutorial, mention your issue in the comment section or reach me through my E-mail. You can obtain complete source code for this tutorial from this GitHub repository.