DEV Community

Debajyoti Das
Debajyoti Das

Posted on • Updated on

JWT auth using Laravel Passport in Laravel 10

composer require laravel/passport -W
php artisan migrate
php artisan passport:install

In User model:

<?php

namespace App\Models;

...
use Laravel\Passport\HasApiTokens;

class User extends Authenticatable
{
    use HasApiTokens, HasFactory, Notifiable;

    ...
}
Enter fullscreen mode Exit fullscreen mode

In config/auth.php:

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

    'api' => [
        'driver' => 'passport',
        'provider' => 'users',
    ],
],
Enter fullscreen mode Exit fullscreen mode

php artisan passport:keys
php artisan vendor:publish --tag=passport-config

Added an extra feature in AuthServiceProvider:

<?php
...
use Laravel\Passport\Passport;

class AuthServiceProvider extends ServiceProvider
{
    ...
    public function boot()
    {
        $this->registerPolicies();
        Passport::tokensExpireIn(now()->addDays(15));
    }
}
Enter fullscreen mode Exit fullscreen mode

If personal client key is not set:
php artisan passport:client --personal

AuthController:

<?php

namespace App\Http\Controllers;

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

class AuthController extends Controller
{
    //
    protected $data = [];
    protected $rules = [];

    public function register(Request $request)
    {
        // Validate input
        $this->rules = [
            'name' => 'required',
            'email' => 'required|email|unique:users',
            'password' => 'required|min:6',
        ];
        $validator = Validator::make($request->all(), $this->rules);

        if($validator->fails())
        {
            return response()->json(['code'=>400, 'message'=>$validator->errors()], 200);
        }

        // Create new user
        User::create([
            'name' => $request->name,
            'email' => $request->email,
            'password' => Hash::make($request->password),
        ]);

        return response()->json(['code'=>200, 'message' => 'Registered Successfully!', 'data'=>$this->data], 200);
    }

    public function login(Request $request)
    {
        // Validate input
        $this->rules = [
            'email' => 'required|email',
            'password' => 'required',
        ];
        $validator = Validator::make($request->all(), $this->rules);

        if($validator->fails())
            return response()->json(['code'=>400, 'message'=>$validator->errors()], 200);

        // Attempt to authenticate
        if (Auth::attempt(['email' => $request->email, 'password' => $request->password])) {
            // Issue access token
            $this->data['token'] = 'Bearer '.auth()->user()->createToken('TestProject', ['*'])->accessToken;

            return response()->json(['code'=>200, 'message' => 'Sign in successful!', 'data'=>$this->data], 200);
        }
        else
            return response()->json(['code'=>200, 'message'=>'Creds not matching!', 'data'=>$this->data], 200);

    }

    public function user()
    {
        // Retrieve the authenticated user
        $this->data['user'] = auth()->user();
        if($this->data['user'] == null)
            return response()->json(['code'=>200, 'message'=>'Invalid Token', 'data'=>$this->data], 200);

        return response()->json(['code'=>200, 'message' => 'Records retrieved!', 'data'=>$this->data], 200);
    }

    public function logout () 
    {
        $token = auth()->user()->token();
        $token->revoke();
        return response()->json(['code'=>200, 'message'=>'You have been successfully logged out!', 'data'=>$this->data], 200);
    }
}

Enter fullscreen mode Exit fullscreen mode

When making API calls, sending application/json in Header's Accept key is always a good idea as it will return the following if bearer token mismatches:

{
    "message": "Unauthenticated."
}
Enter fullscreen mode Exit fullscreen mode

Btw default postman will pass / in Header's Accept key which will throw the following error or head render the /login page:

Route [login] not defined. in file
Enter fullscreen mode Exit fullscreen mode

The above code can be found in Authenticate middleware

Top comments (0)