skip to Main Content

I am trying to make login functionality using JWT in Laravel 10. The issue I have is that I have base User class and Artist and Client as inherited classes. The query done by JWTAuth queries the artists table looking for property ‘username’, but that property is in User class. This is my code in the controller.

<?php

namespace AppHttpControllers;

use AppRepositoriesimplUserRepositoryImpl;
use IlluminateHttpRequest;
use IlluminateSupportFacadesLog;
use IlluminateSupportFacadesValidator;
use PHPOpenSourceSaverJWTAuthJWTAuth;

class LoginController extends Controller
{
protected $jwt;
protected $userRepo;

public function __construct(JWTAuth $jwt, UserRepositoryImpl $userRepo)
{
    $this->jwt = $jwt;
    $this->userRepo = $userRepo;
}

public function login(Request $request)
{
    $validator = Validator::make($request->all(), [
        'username' => 'required|string',
        'password' => 'required|string',
    ]);

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

    $credentials = $request->only('username', 'password');

    if (!$token = $this->jwt->attempt($credentials)) {
        Log::error('Authentication failed for credentials: ', $credentials);
        return response()->json(['message' => 'Invalid credentials'], 401);
    }

    $user = $this->userRepo->findByUsername($credentials['username']);

    if (!$user) {
        return response()->json(['message' => 'User not found'], 404);
    }

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

and with a bit of debugging I think the code $this->jwt->attempt($credentials) is making the issue, I am just not sure why.

Edit:
By following Raju’s input I am still getting the same error:

[2024-09-01 11:46:45] local.DEBUG: Attempting to authenticate with                     
credentials:  {"username":"newclient","password":"stefan123"} 
[2024-09-01 11:46:45] local.ERROR: SQLSTATE[42703]: Undefined 
column: 7 ERROR:  column "username" does not exist
LINE 1: select * from "artists" where "username" = $1 limit 1
                                  ^ (Connection: pgsql, SQL: 
select * from "artists" where "username" = newclient limit 1) 

2

Answers


  1. You should be able to correct the issue where JWTAuth queries the artists table instead of the users table. If you continue facing problems, consider checking for any customizations in the JWTAuth package or Laravel that might affect the authentication flow.

    Check the JWTAuth Configuration

    'providers' => [
        'users' => AppModelsUser::class,
    ],
    

    Customizing JWTAuth to Handle Inheritance

    namespace AppProviders;
    
    use PHPOpenSourceSaverJWTAuthProvidersAuthIlluminate;
    use IlluminateContractsAuthUserProvider as UserProviderContract;
    
    class CustomJwtProvider extends Illuminate
    {
        public function retrieveById($identifier)
        {
            return User::find($identifier);
        }
    
        public function retrieveByToken($identifier, $token)
        {
            return User::where('id', $identifier)->first();
        }
    
        public function updateRememberToken(UserProviderContract $user, $token)
        {
            // No-op
        }
    }
    

    In your config/jwt.php file, update the providers section to use the custom provider:

    'providers' => [
        'users' => AppProvidersCustomJwtProvider::class,
    ],
    

    Ensure that your UserRepositoryImpl class is querying the correct User model:

    namespace AppRepositoriesimpl;
    
    use AppModelsUser;
    
    class UserRepositoryImpl
    {
        public function findByUsername($username)
        {
            return User::where('username', $username)->first();
        }
    }
    

    Debugging JWTAuth

    $credentials = $request->only('username', 'password');
    Log::debug('Attempting to authenticate with credentials: ', $credentials);
    
    if (!$token = $this->jwt->attempt($credentials)) {
        Log::error('Authentication failed for credentials: ', $credentials);
        return response()->json(['message' => 'Invalid credentials'], 401);
    }
    
    Login or Signup to reply.
  2.  public function login(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'username' => 'required|string',
            'password' => 'required|string',
        ]);
    
        if ($validator->fails()) {
            return response()->json(['errors' => $validator->errors()], 422);
        }
    
        $credentials = $request->only('username', 'password');
    
        // Using the injected userRepo to find the user by username
        $user = $this->userRepo->findByUsername($credentials['username']);
    
        if (!$user) {
            return response()->json(['message' => 'User not found'], 404);
        }
    
        // Attempt to authenticate the user using the injected JWTAuth
        if (!$token = $this->jwt->fromUser($user)) {
            Log::error('Authentication failed for credentials: ', $credentials);
            return response()->json(['message' => 'Invalid credentials'], 401);
        }
    
        return response()->json([
            'token' => $token,
            'role' => $user->role,
        ], 200);
    }
    
    • ensure that any necessary protected or public properties are properly inherited in your Model like Fillable Properties, Table Name (if it is necessary)
    • Make sure that your User model is the one being used by the JWTAuth

    try this if it is still not solving the problem then let me know!!

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search