Laravel 6.2 REST API CRUD with Passport Authentication Tutorial

In this tutorial, I’m going to create RESTful API Passport Authentication in Laravel 6.2. Using Laravel, we can easily create API. I’m going to make a REST API to create, read, update and delete books. Let’s follow these simple steps:

Table of Contents

  1. Install Laravel and Basic Configurations
  2. Install Passport
  3. Configure Passport
  4. Create User Controller
  5. Create Model, Migration & Controller
  6. Register API Routes
  7. Test the Application

Step 1 : Install Laravel and Basic Configurations

Each Laravel project needs this thing. That’s why I have written an article on this topic. Please see this part from here: Install Laravel and Basic Configurations.

Step 2 : Install Passport

Install the passport using this artisan command:

composer require laravel/passport

To create passport tables, we need to run this command:

php artisan migrate

Now let’s create token keys for security:

php artisan passport:install

Step 3 : Configure Passport

We need to modify two files to run the passport auth. First, we have to add HasApiTokens in the User model.

app/User.php
use Laravel\Passport\HasApiTokens;

class User extends Authenticatable
{
    use Notifiable, HasApiTokens;
    // .....
}

Second, in auth.php, we need to set api driver as passport. Let’s do it:

config/auth.php
return [
    // .....
    'guards' => [
        'web' => [
            'driver' => 'session',
            'provider' => 'users',
        ],
        'api' => [
            'driver' => 'passport',
            'provider' => 'users',
            'hash' => false,
        ],
    ],
    // .....
]

Step 4 : Create User Controller

We will register & login user using API and provide a token on the register. So, we need a controller. Run this artisan command to create a controller named UserController.

php artisan make:controller API\UserController

Then open the controller from app\Http\Controllers\API folder and paste this code:

UserController.php
<?php

namespace App\Http\Controllers\API;

use Illuminate\Http\Request;
use App\User;
use Illuminate\Support\Facades\Auth;
use Validator;

class UserController
{
    /**
     * User Register
     */
    public function register(Request $request)
    {
        // validate
        $validator = Validator::make($request->all(), [
            'name' => 'required',
            'email' => 'required|email',
            'password' => 'required',
            'c_password' => 'required|same:password',
        ]);
        if ($validator->fails()) {
            // return response
            $response = [
                'success' => false,
                'message' => 'Validation Error.', $validator->errors(),
            ];
            return response()->json($response, 404);
        }

        // insert to DB
        $input = $request->all();
        $input['password'] = bcrypt($input['password']);
        $user = User::create($input);
        $accessToken = $user->createToken('ApplicationName')->accessToken;

        // return response
        $response = [
            'success' => true,
            'message' => 'User registration successful',
            'accessToken' => $accessToken,
        ];
        return response()->json($response, 200);
    }

    /**
     * User Login
     */
    public function login(Request $request)
    {
        if (Auth::attempt(['email' => $request->email, 'password' => $request->password])) {
            // return response
            $response = [
                'success' => true,
                'message' => 'User login successful',
            ];
            return response()->json($response, 200);
        } else {
            // return response
            $response = [
                'success' => false,
                'message' => 'Unauthorised',
            ];
            return response()->json($response, 404);
        }
    }
}

Step 5 : Create Model, Migration & Controller

In this step, we are going to create the book model, migration and controller. Let’s create these at once:

php artisan make:model Book -mcr

After creating the files, open the migration file from database/migrations and update the up() function like this:

timestamp_create_books_table.php
public function up()
{
    Schema::create('books', function (Blueprint $table) {
        $table->bigIncrements('id');
        $table->string('name');
        $table->string('author');
        $table->timestamps();
    });
}

We’ve to migrate the migration:

php artisan migrate

After that open Book model and add a $fillable array:

app/Book.php
<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Book extends Model
{
    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $fillable = [
        'name', 'author'
    ];
}

Lastly, open BookController from app\Http\Controllers\API and paste this code:

BookController.php
<?php

namespace App\Http\Controllers\API;

use Illuminate\Http\Request;
use App\Book;
use Validator;

class BookController
{
    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function index()
    {
        $books = Book::all();

        // return response
        $response = [
            'success' => true,
            'message' => 'Books retrieved successfully.',
            'products' => $books,
        ];
        return response()->json($response, 200);
    }

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

        $validator = Validator::make($input, [
            'name' => 'required',
            'author' => 'required'
        ]);

        if ($validator->fails()) {
            // return response
            $response = [
                'success' => false,
                'message' => 'Validation Error.', $validator->errors(),
            ];
            return response()->json($response, 404);
        }

        $book = Book::create($input);

        // return response
        $response = [
            'success' => true,
            'message' => 'Book created successfully.',
        ];
        return response()->json($response, 200);
    }

    /**
     * Display the specified resource.
     *
     * @param int $id
     * @return \Illuminate\Http\Response
     */
    public function show($id)
    {
        $book = Book::find($id);

        if (is_null($book)) {
            // return response
            $response = [
                'success' => false,
                'message' => 'Book not found.',
            ];
            return response()->json($response, 404);
        }

        // return response
        $response = [
            'success' => true,
            'message' => 'Book retrieved successfully.',
        ];
        return response()->json($response, 200);
    }

    /**
     * Update the specified resource in storage.
     *
     * @param \Illuminate\Http\Request $request
     * @param int $id
     * @return \Illuminate\Http\Response
     */
    public function update(Request $request, Book $book)
    {
        $input = $request->all();

        $validator = Validator::make($input, [
            'name' => 'required',
            'author' => 'required'
        ]);

        if ($validator->fails()) {
            // return response
            $response = [
                'success' => false,
                'message' => 'Validation Error.', $validator->errors(),
            ];
            return response()->json($response, 404);
        }

        $book->name = $input['name'];
        $book->author = $input['author'];
        $book->save();

        // return response
        $response = [
            'success' => true,
            'message' => 'Book updated successfully.',
        ];
        return response()->json($response, 200);
    }

    /**
     * Remove the specified resource from storage.
     *
     * @param int $id
     * @return \Illuminate\Http\Response
     */
    public function destroy(Book $book)
    {
        $book->delete();

        // return response
        $response = [
            'success' => true,
            'message' => 'Book deleted successfully.',
        ];
        return response()->json($response, 200);
    }
}

In this file, I’ve written the CRUD functions.

Step 6 : Register API Routes

Our application is about to finish. In this step, we are going to define the API routes to register & login user and will set a resource route for the BookController.

routes/api.php
Route::post('register', 'API\UserController@register');
Route::post('login', 'API\UserController@login');

Route::middleware('auth:api')->group( function () {
    Route::resource('books', 'API\BookController');
});

Step 7 : Test the Application

We have completed all the tasks. Let’s run the app using php artisan serve command. Now, our application is running. We will use Postman to call our APIs.

Note: we’ve to send two headers at the time of calling APIs:

'headers' => [
    'Accept' => 'application/json',
    'Authorization' => 'Bearer '.$accessToken,
]

Let’s call the APIs.

User Registration API: http://localhost:8000/api/register

User Login API: http://localhost:8000/api/login

Create Book API:http://localhost:8000/api/books

Retrieve Book API:http://localhost:8000/api/books

Update Book API:http://localhost:8000/api/books/{id}

Delete Book API:http://localhost:8000/api/books/{id}

The tutorial is over. You can download this project from GitHub. Thank you. ?