DEV Community

Cover image for Vue App with Lumen Passport API (Part II)
Ezichi Ebere Ezichi
Ezichi Ebere Ezichi

Posted on

Vue App with Lumen Passport API (Part II)

Auth or Auth?

Typically in Software development, there's need for some level of security wherever there is data involved. Authentication is the process of identifying who wants to access the data. Authorization on the other hand involves checking the access level of the person. With Passport we can achieve that.

What we'll build

As stated in Part I, the finished app will be a contacts app for users to save their contacts. In this part we will set up the API's with login and registration.

Without further ado...

Setup Auth Controller and Routes

Before creating the controller, let's create a common success response in our base controller.

<?php

namespace App\Http\Controllers;

use Laravel\Lumen\Routing\Controller as BaseController;

class Controller extends BaseController
{
    public function return_success($message, $data = [], $status = 200)
    {
        return [
            "message" => $message,
            "data" => $data,
            "status" => $status
        ];
    }
}
Enter fullscreen mode Exit fullscreen mode

Now let's create the controller with the command.

php artisan make:controller AuthController

We will add a registration and login methods to this controller.

<?php

namespace App\Http\Controllers;

use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Str;
use Symfony\Component\HttpFoundation\Response;

class AuthController extends Controller
{
    public function login(Request $request)
    {
        $this->validate($request, [
            'email' => 'required',
            'password' => 'required'
        ]);

        $user = User::where('email', $request->email)->first();
        if ($user) {
            if (Hash::check($request->password, $user->password)) {
                $token = $user->createToken('Laravel Password Grant Client')->accessToken;

                return $this->return_success("Login successful", ["token" => $token], Response::HTTP_OK);
            } else {
                $response = ["message" => "Password mismatch"];
                return response($response, 422);
            }
        } else {
            $response = ["message" => 'User does not exist'];
            return response($response, 422);
        }
    }

    public function register(Request $request)
    {
        $this->validate($request, [
            'name' => 'required|string|max:255',
            'email' => 'required|string|email|max:255|unique:users',
            'password' => 'required|string|min:6|confirmed',
        ]);

        $request['password'] = Hash::make($request['password']);
        $request['remember_token'] = Str::random(10);
        $user = User::create($request->toArray());
        $token = $user->createToken('Laravel Password Grant Client')->accessToken;

        return $this->return_success("User created successfully", ["user" => $user, "token" => $token], Response::HTTP_CREATED);
    }
}

Enter fullscreen mode Exit fullscreen mode

We have our login and registration methods in our controller, we can create the corresponding routes in our routes file i.e routes/web.php.

$router->group(['prefix' => 'auth'], function() use ($router) {
    $router->post('login', 'AuthController@login');
    $router->post('register', 'AuthController@register');
});
Enter fullscreen mode Exit fullscreen mode

Test auth routes with postman

We register a user with postman
Image description

Registration is successful!!!

Let's try to login with the email and password we registered with.
Image description

Login is successful!!!

Now, with the generated token after login, we can access authorized routes. Next, we will create the Contact model, migration and routes.

Setup Contacts

We'll use the command to create model, migration and controller for contacts.

php artisan make:model Contact -mc

Add necessary fields in migration.

Schema::create('contacts', function (Blueprint $table) {
    $table->id();
    $table->foreignId('owner_id');
    $table->string('name');
    $table->string('email')->nullable();
    $table->string('phone_number')->unique();
    $table->date('birthday')->nullable();
    $table->timestamps();
});
Enter fullscreen mode Exit fullscreen mode

The model will look like this:

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;

class Contact extends Model
{
    protected $fillable = [
        'name',
        'email',
        'phone_number',
        'birthday',
        'owner_id'
    ];

    public function owner(): BelongsTo
    {
        return $this->belongsTo(User::class, 'owner_id');
    }
}
Enter fullscreen mode Exit fullscreen mode

For the controller, we will add the crud methods needed.

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class ContactController extends Controller
{
    public function index()
    {
        return $this->return_success("My contacts", auth('api')->user()->contacts, 200);
    }

    public function show($id)
    {
        /** @var User $user */
        $user = auth('api')->user();

        return $this->return_success("My contact", $user->contacts()->where('id', $id)->first(), 200);
    }

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

        /** @var User $user */
        $user = auth('api')->user();

        $user->contacts()->create([
            'name' => $request->get('name'),
            'phone_number' => $request->get('phone_number'),
            'birthday' => $request->get('birthday'),
            'email' => $request->get('email')
        ]);

        return $this->return_success("My contacts", $user->contacts()->latest()->get(), 200);
    }

    public function update(Request $request, $id)
    {
        $this->validate($request, [
            'name' => 'required',
            'phone_number' => 'required'
        ]);

        /** @var User $user */
        $user = auth('api')->user();
        $contact = $user->contacts()->find($id);

        $contact->update([
            'name' => $request->get('name'),
            'phone_number' => $request->get('phone_number'),
            'birthday' => $request->get('birthday'),
            'email' => $request->get('email')
        ]);

        return $this->return_success("Contact updated", $contact, 200);
    }

    public function destroy($id)
    {
        /** @var User $user */
        $user = auth('api')->user();
        $contact = $user->contacts()->find($id);

        $contact->delete();

        return $this->return_success("Contact deleted", NULL, 200);
    }
}

Enter fullscreen mode Exit fullscreen mode

Let's run our migration.

php artisan migrate

Add contacts relationship in User model.

public function contacts(): HasMany
{
    return $this->hasMany(Contact::class, 'owner_id');
}
Enter fullscreen mode Exit fullscreen mode

Finally, we add the routes.

$router->group(['middleware' => 'auth:api'], function() use ($router) {
    $router->get('contacts', 'ContactController@index');
    $router->get('contacts/{id}', 'ContactController@show');
    $router->post('contacts', 'ContactController@store');
    $router->patch('contacts/{id}', 'ContactController@update');
    $router->delete('contacts/{id}', 'ContactController@destroy');
});
Enter fullscreen mode Exit fullscreen mode

Test with Postman

First, you have to login. Copy the token generated and we will use it to create a contact.
Image description

Provide necessary fields for creating a contact.
Image description

Congratulations, you have created a contact for a logged user.

In the next tutorial, we'll finish up the app and push it to Github.

Top comments (0)