MissionaryZeal

Auth using JWT Laravel

composer create-project laravel/laravel lara-api-jwt
cd lara-api-jwt

Connect the database in .env

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=lara-api-jwt
DB_USERNAME=root
DB_PASSWORD=

Make Migration

php artisan migrate

If don’t create a database manually in my XAMPP server and then ask to create a database after hitting migrate just press ‘y’

Install & Setup JWT

composer require php-open-source-saver/jwt-auth

Next, we have to publish the package configuration

php artisan vendor:publish --provider="PHPOpenSourceSaver\JWTAuth\Providers\LaravelServiceProvider"

Now we need to generate a secret key for handling the token encryption.

php artisan jwt:secret

Configure the authGuard

Inside the config/auth.php we will need to change a few things. We have to tell the API guard to use the JWT and the default guard is the API

   'defaults' => [
        'guard' => 'api',
        'passwords' => 'users'
    ],


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

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

Modify the User model

To implement PHPOpenSourceSaver contract on our User modal. We will use two methods: getJWTIdentifier(), and getJWTCustomClaims()


<?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\Sanctum\HasApiTokens;
use PHPOpenSourceSaver\JWTAuth\Contracts\JWTSubject;

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

    /**
     * The attributes that are mass assignable.
     *
     * @var array<int, string>
     */
    protected $fillable = [
        'name',
        'email',
        'phone',
        'password',
    ];

    /**
     * The attributes that should be hidden for serialization.
     *
     * @var array<int, string>
     */
    protected $hidden = [
        'password',
        'remember_token',
    ];

    /**
     * The attributes that should be cast.
     *
     * @var array<string, string>
     */
    protected $casts = [
        'email_verified_at' => 'datetime',
    ];


    /**
     * Get the identifier that will be stored in the subject claim of the JWT.
     *
     * @return mixed
     */
    public function getJWTIdentifier()
    {
        return $this->getKey();
    }

    /**
     * Return a key value array, containing any custom claims to be added to the JWT.
     *
     * @return array
     */
    public function getJWTCustomClaims()
    {
        return [];
    }
}

Create the AuthController

php artisan make:controller AuthController

Below is the controller’s code for the auth

<?php

namespace App\Http\Controllers;

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

class AuthController extends Controller
{

    /**
     * Register new user
     * @method api/user/register
     * @return JSON
     * */
    public function register(Request $request)
    {

        $request->validate([
            'name' => 'required|string|max:255',
            'email' => 'required|string|email|max:255|unique:users',
            'phone' => 'required|numeric|digits:10',
            'password' => 'required|string|confirmed',
        ]);

        $data = $request->except(['_token']);

        $data['password'] = Hash::make($data['password']);

        try {
            $user = User::create($data);
            $token = Auth::login($user);

            return response()->json([

                'success' => true,
                'message' => 'User created successfully',
                'user' => $user,
                'token' => $token
            ], 201);
        } catch (\Exception $e) {
            return response()->json(['error' => $e], 500);
        }
    }


    /**
     * Login user
     * @method api/user/login
     * @return JSON
     * */
    public function login(Request $request)
    {

        $request->validate([

            'email' => 'required|string|email|max:255',
            'password' => 'required|string'
        ]);

        try {
            $credentials = $request->only('email', 'password');

            if (!Auth::attempt($credentials)) {
                return response()->json([
                    'success' => false,
                    'message' => 'Unauthorized credentials',
                ], 401);
            }

            $token = Auth::attempt($credentials);
            $user = Auth::user();

            return response()->json([
                'success' => true,
                'message' => 'User login successfully',
                'user' => $user,
                'token' => $token
            ], 200);
        } catch (\Exception $e) {
            return response()->json(['error' => $e], 500);
        }
    }


    /**
     * Get user profile
     * @method api/user/profile
     * @return JSON
     * */
    public function profile(Request $request)
    {
        $user = $request->user();
        return response()->json([
            'success' => true,
            'profile' => $user
        ], 200);
    }


    /**
     * Logout user
     * @method api/user/logout
     * @return JSON
     * */
    public function logout(Request $request)
    {
        Auth::logout();
        return response()->json([
            'success' => true,
            'message' => 'User logout successfully',
        ], 200);
    }
}

Add the routes for the API

To access the controller’s methods, we need to define routes in api.php

<?php

use App\Http\Controllers\AuthController;
use Illuminate\Support\Facades\Route;

Route::controller(AuthController::class)->group(function () {

    Route::group(['prefix' => 'user'], function () {

        Route::post('register',  'register');
        Route::post('login',  'login');

        Route::middleware('auth:api')->group(function () {
            Route::get('profile',  'profile');
            Route::post('logout',  'logout');
        });
    });
});

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top