Hi,
I have a problem using following code:
public function authenticate(Request $request)
{
$credentials = $request->only('email', 'password');
try {
// verify the credentials and create a token for the user
if (! $token = JWTAuth::attempt($credentials)) {
return response()->json(['error' => 'invalid_credentials'], 401);
}
} catch (JWTException $e) {
// something went wrong
return response()->json(['error' => 'could_not_create_token'], 500);
}
// if no errors are encountered we can return a JWT
return response()->json(compact('token'));
}
Im sending the login data via POST. The user account exists in the database. I can echo the login data in the function. For any reason I dont know, I can not authenticate, it always throws 401.
Can you please provide me a solution for that? Or any workaround?
Im using laravel 5.1._, jwt-auth 0.5._ and Apache 2.2.22 (Debian)
Best regards,
Oliver
I had a similar issue when migrating an existing database scheme to use this library. My issue was related to the database scheme differences on the User table. Laravel was Hashing the passwords differently with a longer lenth than my database column was able to hold.
I imagine you have a similar issue that when retrieving from the database it's blowing up.
Here's a couple of things to try:
app/Http/Kernel.php make sure \App\Http\Middleware\VerifyCsrfToken::class is commented out.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'
If you moved your User model don't forget to also update the _user_ key in config/jwt.php.
'user' => '<your User Model>',
Hey guys,
thanks for the help. What you mentioned brought me on the right track. Im building a new authentication from scratch without migrations of any existing users. So what I did for testing was to create users with non hashed passwords in the database, e.g. username: test, password: 123
It seems like the jwt authentication is just working with the laravel Hash::make function since it hashes the POST password to compare with the password from database. So I had to create a user with a laravel hashed password which worked out perfectly fine. Thanks!
Awesome! Glad you figured it out.
@tymondesigns I'm having a similar issue with @OFranke. I'm using a different model which I have set in jwt.php. However, credentials exist in the database - "vendors" table but JWTAuth::attempt($credentials) keeps returning false.
Kindly help with troubleshooting.
/*
* Authenticates the vendors | login */
public function login (request $request) {
// Gets the vendors credentials from the user's login request
$credentials['mobile_number'] = $request->get('mobile_number');
$credentials['password'] = $request->get('password');
try {
// Tries to authenticate vendor
if (! $token = JWTAuth::attempt($credentials)){
// authentication fails
return response()->json(['success' => false], Response::HTTP_UNAUTHORIZED);
}
}catch (JWTException $je){
// something went wrong whilst attempting to encode the token
return response()->json(['error' => 'could_not_create_token'], 500);
}catch (TokenExpiredException $e) {
return response()->json(['token_expired'], $e->getStatusCode());
} catch (TokenInvalidException $e) {
return response()->json(['token_invalid'], $e->getStatusCode());
}
// Authentication successful; generates token
return response()->json(compact('token'));
}
Thanks in advance.
If you are using Laravel make sure that the user passwords stored in the database are hashed with the Laravel algorithm.
Also make sure that you defined your custom user table in the laravel config.
Best regards,
Oliver
Thanks for your prompt reponse @OFranke I actually used bcrypt for the password and Config::set('auth.model', 'App\Vendor');
Config::set('auth.table', 'vendors'); sets the model and table. I've checked all I need to do but all it's still not authenticating.
I spent hours trying to figure out the same problem, thanks @OFranke !
After spending hours I have fixed this by defining primary key in the User model class as
protected $primaryKey = 'user_id';
My User table primary key was different than just defining "id".
I am having same problem as @jidesakin . Have been stuck on this for days.
My problems is in retrieving the user from JWT token.
JWTAuth::parseToken()->authenticate();
Is always returning false. When I look in JWTAuth.php I find the authenticate method is using AuthInterface byId() method to authenticate the user, but as I search through my codes, I can find no implementation as to this method.
public function authenticate($token = false)
{
$id = $this->getPayload($token)->get('sub');
if (! $this->auth->**byId($id)**) {
return false;
}
return $this->auth->user();
}
The implementation of byId() can be found in IlluminateAuthAdapter. It simply calls Auth::onceUsingId(), which is a Laravel function. Are you certain your token has a subject matching a user's ID?
I think that was my problem. I was trying to create a new user with an id of 1. It seems authenticate byId() will look into your db at some point (I don't know, does it?) and try and retrieve this user, which doesn't exist yet. So it will return false.
Thinking this is the source of my problem. Will test with a user in the DB and see if this solves the problem.
Yep, in most cases Auth::onceUsingId($id) calls User::find($id), which will make a DB call to find the user.
You need the user to exist in order to authenticate them. This is true for the base Laravel authentication (how can you log in as a user that doesn't exist?), but even more so for JWTs because they usually only store the user's ID and no other information about them.
Thanks @tdhsmith . Think I have enough info to move forward. Will post solution if/when I find one.
Hello guys,
I would like to share so that others can save a lot of time.
I was using postman to test the API. The password I entered in the form is not the one being sent to the server.
Postman seemed to be using a cashed password from an earlier session to register the user. So when I tried to log on, it failed all the time.
Postman may have a bug or I misinterpreted the UI. The lesson here is to use different method to test from client-end too.
cheers
If your code is correct, then also if your getting output:
{
"error": "invalid_credentials"
}
dd($request->only('email', 'password')); or dd($credentials);
// output should be like this..
array:2 [
"email" => "[email protected]"
"password" => "test123"
]
dd($token);
// output should be:
false
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'
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'
],_
I have an issue about changing $primaryKey. After changing primaryKey in User Model to 'user_id, JWT creates a token but cannot authenticate the user as returning 'user_not_found'. When I look up the token, sub value is just my user's id, not user's user_id. Then I changed the jwt-auth\srcconfigconfig.php file identifier from id to user_id. However still in the token, sub is my id column. Why is it not working?
User Model:
protected $primaryKey = 'user_id';
public $incrementing = false;
Config.php:
'identifier' => 'user_id',
@jidesakin I have samme problem, did you find the answer?
The problem causing this is:
In your database your user password is been stored as plain text. Ensure to hash or bcrypt your password before storing in your database.
Hello i'm facing a 401 Unauthorized Error, it worked fine in my localhost environment, then when i uploaded the code to my live server i get the error after authentication and getting the token to use to make api calls. But the confusion is, it works fine in my other domain hosted by another hosting site, ( i used this to test it before uploading to my main hosting site). But now it's uploaded to iPage, i get the 401 error, and it's the exact same code as the one in my other hosting server. Any ideas?
Most helpful comment
Hey guys,
thanks for the help. What you mentioned brought me on the right track. Im building a new authentication from scratch without migrations of any existing users. So what I did for testing was to create users with non hashed passwords in the database, e.g. username: test, password: 123
It seems like the jwt authentication is just working with the laravel Hash::make function since it hashes the POST password to compare with the password from database. So I had to create a user with a laravel hashed password which worked out perfectly fine. Thanks!