I've created a barebones controller that has the demo code in to fetch a user from a token, but i'm getting an error 'Call to a member function toUser() on boolean' when I try to run the toUser() method.
My code to replicate:
{
$user = JWTAuth::parseToken()->toUser();
}
catch(Tymon\JWTAuth\Exceptions\TokenExpiredException $e)
{
// token has expired
return Response::json(['error' => 'token_expired'], 401);
}
if (! $user)
{
// user not found
return Response::json(['error' => 'user_not_found'], 404);
}
dd($user);
Hi drawmyattention,
Looks like it's caused by JWTAuth returning false when it's unable to parseToken().
You could check for token parsing success before fetching the user, ie:
if (! $auth = JWTAuth::parseToken();) {
throw Exception('JWTAuth unable to parse token from request');
}
$user = $auth->toUser();
You were right, it wasn't able to parse the token from a POST parameter. I had to set the token in a header (my mistake).
However, now when I send a request with an Authorisation bearer {token} header, the parseToken() method no longer kicks out an error, but the toUser() method results in
'Wrong number of segments'
I'm generating the token using:
$user = User::find(1);
$token = JWTAuth::fromUser($user);
dd($token);
Then copying the token generated:
eyJhbGXXXXXXXXXXIkpXUyJ9.eyJzdWIiOjEsImlzcyI6Imh0dHA6XC9cL2w1LmFwcFwvaG9tZSIsImlhdCI6IjE0MjM0NzMyNzciLCJleHAiOiIxNDIzNXXXXXXXXX3MjI2YWFjY2RmIn0.NTI3ZWUyMzUzMWUzMzY2ZTViNDk3ZjBjNTEyYjVjZmI3MXXXXXXXXXXXOWNjNzg0Mw
to use in the auth header.
I've added a bit of debugging to my code to try to quickly see what's going on, and it looks like the validateStructure() method is called twice. The first time, a token is present but the second time an empty token is being passed, which is causing the Exception to be thrown.
Thanks, I will have a look into this.
Note: I think I will change it so that parse token will throw an exception instead of returning false if the token cannot be extracted from the request.
Hi! Any news on this?
When I'm doing a authentication and sending token as response to JS app, it works fine.
The JS app sets the cookie and sends it with header.
However, when I set it from Laravel using Laravel cookie helper, it gives me 'Wrong number of segments'
This is what fails currently
$token = JWTAuth::fromUser($user);
$expire = 60 * 60 * 24 * 90;
$cookieJar->queue(cookie('token', $token, $expire, null, null, null, false));
return redirect('app');
I can verify the token is being generated correctly and the JS app is returning the cookie generated by laravel.
As you can see, I set the http only flag as false too. Tried without that as well.
Any ideas?
Thank you so much for the excellent library
@tymondesigns
@shah-newaz I'm not sure if this is related to your issue, but I had a problem with the fact that laravel encrypts cookies. I have made a middleware that checks the token, and this middleware is (apparently) called before the EncryptCookies middleware has a chance to be called. Therefore instead of something like:
JWTAuth::setToken($request->cookie('token'));
It was necessary instead to write:
JWTAuth::setToken(Crypt::decrypt($request->cookie('token')));
Again, this might not be 100% relevant for your issue, but perhaps some else experienced the same as me :)
Hi @k4kuz0 !
Was exactly my issue :) I found it out thankfully and solved by adding the token to the $except array of Laravels EncryptCookies middleware (App\Http\MiddlewareEncryptCookies.php)
```
namespace App\Http\Middleware;
use Illuminate\Cookie\MiddlewareEncryptCookies as BaseEncrypter;
class EncryptCookies extends BaseEncrypter
{
/**
* The names of the cookies that should not be encrypted.
*
* @var array
*/
protected $except = [
'token'
];
}
```
Like so.
Cheers!
@shah-newaz Glad you found a solution! However note that if you use the solution I mentioned, you can keep the token encrypted, perhaps unnecessary, but extra security is always nice!
@k4kuz0 Hmm, I think you're decrypting the token by Crypt::decrypt($request->cookie('token')
The token is already encrypted. Laravel was double encrypting it. Which was the issue. I can be wrong.
Thanks again!
Most helpful comment
@shah-newaz I'm not sure if this is related to your issue, but I had a problem with the fact that laravel encrypts cookies. I have made a middleware that checks the token, and this middleware is (apparently) called before the
EncryptCookiesmiddleware has a chance to be called. Therefore instead of something like:JWTAuth::setToken($request->cookie('token'));It was necessary instead to write:
JWTAuth::setToken(Crypt::decrypt($request->cookie('token')));Again, this might not be 100% relevant for your issue, but perhaps some else experienced the same as me :)