Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

L5 - Call to a member function toUser() on boolean #35

Closed
amochohan opened this issue Feb 6, 2015 · 8 comments
Closed

L5 - Call to a member function toUser() on boolean #35

amochohan opened this issue Feb 6, 2015 · 8 comments

Comments

@amochohan
Copy link

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:

try
    {
        $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);
@agentk
Copy link

agentk commented Feb 7, 2015

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();

@amochohan
Copy link
Author

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.

@tymondesigns
Copy link
Owner

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.

@shah-newaz
Copy link

shah-newaz commented May 1, 2017

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

@k4kuz0
Copy link

k4kuz0 commented Jul 13, 2017

@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 :)

@shah-newaz
Copy link

shah-newaz commented Jul 13, 2017

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\Middleware\EncryptCookies.php)


namespace App\Http\Middleware;

use Illuminate\Cookie\Middleware\EncryptCookies as BaseEncrypter;

class EncryptCookies extends BaseEncrypter
{
    /**
     * The names of the cookies that should not be encrypted.
     *
     * @var array
     */
    protected $except = [
        'token'
    ];
}

Like so.

Cheers!

@k4kuz0
Copy link

k4kuz0 commented Jul 13, 2017

@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!

@shah-newaz
Copy link

@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!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants