0

I am building an api for a mobile app, and I am using JWT to authenticate users. I am trying to implement it in Laravel 5.1.

I keep getting the error: {"error":"user_not_found"} whenever I use the token that was given to me by the authenticate method.

My process:

  1. Authenticate the user using Auth::attempt($credentials)
  2. Get the user from the db using $user = User::where('user_id', Auth::user()->user_id)->first();
  3. Set the Token for the user using

    $token = "";
    try {
        // attempt to verify the credentials and create a token for the user
        if (! $token = JWTAuth::fromUser($user)) {
            return response()->json(['error' => 'invalid_credentials'], 401);
        }
    } catch (JWTException $e) {
            // something went wrong whilst attempting to encode the token
            return response()->json(['error' => 'could_not_create_token'], 500);
    }
    

It is returning a token using this method:

eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOm51bGwsImlzcyI6Imh0dHA6XC9cL3BlZGxyLmRldlwvYXBpXC9sb2dpbiIsImlhdCI6MTQ0OTk2NDQ2NywiZXhwIjoxNDQ5OTY4MDY3LCJuYmYiOjE0NDk5NjQ0NjcsImp0aSI6IjJlMDMyMjA5MjMyZWM1MDVlY2I3YzE4ODFjNDk1MzFmIn0.tbO_fv4WDQ6WgiHtyYJAq2rjnOtaYPq85VO2ja2YVzw

But when trying to authenticate the user using the token, it throws the error {"error":"user_not_found"}.

My routes.php:

Route::any('/login', ['as' => 'login', 'uses' => 'APIController@postLogin']);
Route::group(['middleware' => 'jwt.auth'], function()   {
    Route::any('/users', ['as' => 'users', 'uses' => 'UsersController@getUsers']);
});

If I take the middleware group out, I can access the /users route. I think it is happening somewhere in the GetUserFromToken class in the Tymon\JWTAuth\Middleware namespace as that is the only place that lists the error user_not_found.

My database uses user_id, not just id as primary keys, could this be the issue?

Haring10
  • 1,517
  • 1
  • 19
  • 37

4 Answers4

5

Finally I got it.

I went into the config/jwt.php file that was created when publishing the JWTAuthServiceProvider and then I changed the identifier to the primary key of my Users table (as the user setting is set to App\User, my primary key is user_id in the User model).

'identifier' => 'user_id' // somewhere around line 79

And it worked.

Haring10
  • 1,517
  • 1
  • 19
  • 37
  • Pretty lame :D Could have found that be ready the manual more closely, instead of SOl!!! https://github.com/tymondesigns/jwt-auth/wiki/Configuration – Skid Kadda Dec 13 '15 at 01:34
0

You need a login route, that creates a session first. Then get the user.

Route::post('sessions/create', ['uses' => 'Auth\JwtAuthController@authenticate']);
Route::get('sessions/user', ['uses' => 'Auth\JwtAuthController@getAuthenticatedUser']);

Try the following code in your controller:

/**
 * Authenticate by credentials
 */
public function authenticate()
{

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

    try {

        if ( !$token = JWTAuth::attempt($credentials) ) {
            return $this->error('invalid-credentials', 401);
        }

    } catch (JWTException $e) {
        // something went wrong whilst attempting to encode the token
        return $this->error('could-not-create-token', 500);
    }

    return response()->json(compact('token'));

}


/**
 * Get the user by jwt token, or return an error
 *
 * @return Response
 */
public function getAuthenticatedUser()
{

    try {

        if ( !$user = JWTAuth::parseToken()->authenticate() ) {
            return $this->error('user-not-found', 204);
        }

    } catch (TokenExpiredException $e) {

        return $this->error('token-expired', 401);

    } catch (TokenInvalidException $e) {

        return $this->error('token-invalid', 401);

    } catch (JWTException $e) {

        return $this->error('token-absent', 400);

    }

    // the token is valid and we have found the user via the sub claim
    return response()->json(compact('user'));
}


/**
 * Error formatter
 *
 * @param  string  $message
 * @param  integer $statuscode
 *
 * @return \Illuminate\Http\JsonResponse
 */
private function error($message, $statuscode = 401)
{
    return response()->json(['error' => $message], $statuscode);
}
Skid Kadda
  • 482
  • 3
  • 14
  • But it is giving me the token in the first request – Haring10 Dec 13 '15 at 00:56
  • 1). First you post your login details to /sessions/create. 2). When the token get's back to you..then the user has valid credentials. This means you can then use the token for all further authorization things. – Skid Kadda Dec 13 '15 at 01:06
  • I am doing that, I am getting the token back, I have valid credentials, but the token does not work after that. – Haring10 Dec 13 '15 at 01:11
  • You need to set a Request header with the token. Authorization:Bearer token – Skid Kadda Dec 13 '15 at 01:24
0

Solution...

If your code is correct, then also if your getting output:

{
  "error": "invalid_credentials"
}

Just Follow this Steps:---------------

first step check:

dd($request->only('email', 'password')); or dd($credentials); // output should be like this..

array:2 [
  "email" => "myemail@myemail.com"
  "password" => "test123"
]

second step check:

 dd($token); 

// output should be: false

Third step check:

1) Inside of app/Http/Kernel.php make sure \App\Http\Middleware\VerifyCsrfToken::class is commented out. 2) Inside config/jwt.php make sure you have the identifier set to the primary key of your Users table.

'identifier' => 'userid' // default is set to 'id'

Last Step Goto: App\Config\auth.php

On line number: 70 Change Model Location where your saved model(User)

for example: App\Model\Myuser\User

and

On line number: 71 Change Table Name to what you have set in your model(User)

for example: protected $table = 'my_user';

 'providers' => [
        'users' => [
            'driver' => 'eloquent',
            'model' => App\Models\Myuser\User::class,
            'table' => 'my_user'
        ],

It may help you....

Sharjeel Khan
  • 31
  • 1
  • 1
  • 3
-1

Try it: In User model write the single line: protected $primaryKey = 'user_id';

Example:

class User extends Authenticatable
{
    use Notifiable;

    protected $table = 'my_user';
    protected $primaryKey = 'user_id';
}
lczapski
  • 4,026
  • 3
  • 16
  • 32
Strenuous
  • 41
  • 2