Search code examples
laravellaravel-5jwtjson-web-token

JWT Authentication user_not_found Tymon


I have set up Tymon Package for JWT Authentication. In case of new user sign up or login I get the token successfully. But when I pass the token to the Laravel JWT I get an error as user not found.

controller code

public function authenticate()
    {
        $credentials = request()->only('user_name','password');
        try{
            $token = JWTAuth::attempt($credentials);
            if(!$token){
                return response()->json(['error'=>'invalid_credentials'],401);
            }
        }
        catch(JWTException $e){
            return response()->json(['error'=>'something went wrong'],500);
        }
        return response()->json(['token'=>$token],200);
    }

    public function register()
    {
        $user_name = request()->user_name;
        $c_name = request()->company_name;
        $accessibility_level = request()->accessability_level;
        $password = request()->password;
        $contact_number = request()->contact_number;
        $address = request()->address;

        $user = User::create([
            'user_name'=>$user_name,
            'c_name'=>$c_name,
            'accessibility_level'=>$accessibility_level,
            'password'=>bcrypt($password),
            'contact_number'=>$contact_number,
            'address'=>$address
        ]);

        $token = JWTAuth::fromUser($user);

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

no problem with the above code works fine.

But when I try to access some data with JWT validation I get an error as USER_NOT_FOUND. I have passed the Token which I have got as an header through Postman.

Route Code

Route::get('/some_route','some_controller@index')->middleware('jwt.auth');

And the jwt.php is also set with the correct identifier which I have used in the model(Primary key)

'identifier' => 'user_name',

Solution

  • The JWT identifier doesn't work by simply modifying the config because it's hardcoded as id in the code for some reason

    You can of course use the setIdentifier method before calling any other JWTAuth methods to set the identifier.

    Here's how:

    public function authenticate()
        {
            $credentials = request()->only('user_name','password');
            try{
                $token = JWTAuth::setIdentifier('user_name')->attempt($credentials);
                if(!$token){
                    return response()->json(['error'=>'invalid_credentials'],401);
                }
            }
            catch(JWTException $e){
                return response()->json(['error'=>'something went wrong'],500);
            }
            return response()->json(['token'=>$token],200);
        }
    

    Then create a custom middleware for jwt authentication:

    public function handle($request, \Closure $next)
        {
            if (! $token = $this->auth->setIdentifier('user_name')->setRequest($request)->getToken()) {
                return $this->respond('tymon.jwt.absent', 'token_not_provided', 400);
            }
    
            try {
                $user = $this->auth->authenticate($token);
            } catch (TokenExpiredException $e) {
                return $this->respond('tymon.jwt.expired', 'token_expired', $e->getStatusCode(), [$e]);
            } catch (JWTException $e) {
                return $this->respond('tymon.jwt.invalid', 'token_invalid', $e->getStatusCode(), [$e]);
            }
    
            if (! $user) {
                return $this->respond('tymon.jwt.user_not_found', 'user_not_found', 404);
            }
    
            $this->events->fire('tymon.jwt.valid', $user);
    
            return $next($request);
        }