DecryptException in Encrypter.php line 144:
The payload is invalid.
/vendor/laravel/passport/src/Guards/TokenGuard.php:198
while executing: $this->encrypter->decrypt($this->token) I've got error
while executing code below looks fine.
dd($this->encrypter, $this->token, (array) JWT::decode(
($this->token),
$this->encrypter->getKey(), ['HS256']
));
Encrypter {#393
#key: b"‘=½Ô8î\x12XŸ)0ë’Ç8ÉZ\v9y¤~þU'ß\x06{²¬\x0F\x1A"
#cipher: "AES-256-CBC"
}
"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOjI1NjY1LCJjc3JmIjoiUWRaSWNGSTZTQ3JjbTYyNGRTTk1MVDlacUZ0Z2pEOUk0ZE9nUjZNbyIsImV4cGlyeSI6MTQ4MDI5MTM5Mn0.ZGQ5__JTz4r6tW2E5ST_GL7ATvDa2N06iYRN-D_0hwQ"
array:3 [
"sub" => 25665
"csrf" => "QdZIcFI6SCrcm624dSNMLT9ZqFtgjD9I4dOgR6Mo"
"expiry" => 1480291392
]
Do I use bad encrypter or what?
@mbm-rafal Did you happen to change your APP_KEY environment variable after creating this access token? Also, what version of Passport do you have installed? TokenGuard.php:198 is part of a docblock, so ... the problem might just be your version and you need to upgrade, but we will see.
Also, what are you doing that causes this exception to be thrown (aka what are the steps to reproduce this error).
ping @mbm-rafal
I'm using v1.0.17 of Laravel Passport and can reproduce the error reported by OP.
We're using the CreateFreshApiToken middleware to consume the API via JS and we ensure X-CSRF-TOKEN token is being passed in the header.
@righter Can you post the exact steps to reproduce this error?
@craigpaul, I had a thought which I'll have to verify tomorrow. I didn't add Laravel\Passport\HasApiTokens to my user model. I was thinking it might not be needed because I'm using the CreateFreshApiToken middleware on my web routes. I'm hoping that adding the trait will clear up my issue.
@craigpaul @themsaid
Replication:
Route::group(['prefix' => 'auth', 'middleware' => [/*'auth:api'*/], 'as' => 'Security::'], function () {
Route::get('/jwt', function(\Laravel\Passport\ApiTokenCookieFactory $factory, Request $request) {
$cookie = $factory->make(
25665,
$request->session()->token()
);
return response()->json(['X-CSRF-TOKEN' => $request->session()->token(), 'JWT-TOKEN' => $cookie->getValue()]);
});
});
array:3 [
"sub" => 25665
"csrf" => "sqOj1MSIiRBTQF3ssGOXrEStbzqpyyc0BUBANH5M"
"expiry" => 1482507630
]
b"‘=½Ô8î\x12XŸ)0ë’Ç8ÉZ\v9y¤~þU'ß\x06{²¬\x0F\x1A"
"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOjI1NjY1LCJjc3JmIjoic3FPajFNU0lpUkJUUUYzc3NHT1hyRVN0YnpxcHl5YzBCVUJBTkg1TSIsImV4cGlyeSI6MTQ4MjUwNzYzMH0.WTiSgLw_-AuZlrv91dF4rZhnDzOZ3X4kLjYA1x_-KTM"
HTTP/1.1 500 Internal Server Error
Date: Fri, 23 Dec 2016 13:42:44 GMT
Server: Apache/2.4.6 (CentOS) OpenSSL/1.0.1e-fips PHP/5.6.26
Access-Control-Allow-Origin: https://xxxxxxxxx
X-Powered-By: PHP/5.6.26
Cache-Control: no-cache, private
Set-Cookie: laravel_token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOjI1NjY1LCJjc3JmIjoic3FPajFNU0lpUkJUUUYzc3NHT1hyRVN0YnpxcHl5YzBCVUJBTkg1TSIsImV4cGlyeSI6MTQ4MjUwNzYzMH0.WTiSgLw_-AuZlrv91dF4rZhnDzOZ3X4kLjYA1x_-KTM; expires=Fri, 23-Dec-2016 15:42:44 GMT; Max-Age=7200; path=/; httponly
Access-Control-Allow-Credentials: true
Access-Control-Allow-Methods: POST, GET, OPTIONS, DELETE, PUT
Access-Control-Max-Age: 3600
Access-Control-Allow-Headers: Content-Type, Access-Control-Allow-Headers, Authorization, X-Requested-With, X-CSRF-TOKEN
Connection: close
Transfer-Encoding: chunked
Content-Type: text/html; charset=UTF-8
return (array) JWT::decode(
//$this->encrypter->decrypt($request->cookie(Passport::cookie())),
$this->encrypter->decrypt(array_get($_COOKIE, 'laravel_token', $request->cookie('laravel_token')))
$this->encrypter->getKey(), ['HS256']
);
getting
"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOjI1NjY1LCJjc3JmIjoic3FPajFNU0lpUkJUUUYzc3NHT1hyRVN0YnpxcHl5YzBCVUJBTkg1TSIsImV4cGlyeSI6MTQ4MjUwNzYzMH0.WTiSgLw_-AuZlrv91dF4rZhnDzOZ3X4kLjYA1x_-KTM"
b"‘=½Ô8î\x12XŸ)0ë’Ç8ÉZ\v9y¤~þU'ß\x06{²¬\x0F\x1A"
so there is same token as from ->getValue() same enryption key
if ($dump) {
dd($payload, base64_decode($payload), json_decode(base64_decode($payload), true));
}
with result:
"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOjI1NjY1LCJjc3JmIjoic3FPajFNU0lpUkJUUUYzc3NHT1hyRVN0YnpxcHl5YzBCVUJBTkg1TSIsImV4cGlyeSI6MTQ4MjUwNzYzMH0.WTiSgLw_-AuZlrv91dF4rZhnDzOZ3X4kLjYA1x_-KTM"
b"{"typ":"JWT","alg":"HS256"}{"sub":25665,"csrf":"sqOj1MSIiRBTQF3ssGOXrEStbzqpyyc0BUBANH5M","expiry":1482507630}\x16N$á/\x00.fZ´¸WEÔÂa£<╬gu°É©Ï\x03\JL"
null
Does it make sense?
Maybe the case is transfer but I have pushed valid base64 string which is decoded corectly, seems a different key is bound ?
@craigpaul -- adding the HasApiTokens trait to my user model did not resolve the issue. I'm going to follow the Installation guide for API Authentication on a fresh Laravel 5.3 install and see if I get same results.
Here's a patch file of the changes I made on a fresh Laravel 5.3 install. I followed steps outlined in Larvel API Authentication: Installation. I skipped Frontend Quickstart and picked back up at Consuming your API with javascript.
When I issue the ajax request against api/user I get a 401 Unauthorized response.
The X-CSRF-TOKEN is present within the Request Headers and everything seems like it should be working.
@craigpaul -- I missed the CreateFreshApiToken middleware when I did the fresh install. After adding that, my ajax requests are now returning 200 OK.
This at least gives me a base to work from to determine why I'm not seeing the same results in my application and points to "user error" on my end.
@righter Glad to hear you got it working, if you have any other trouble don't hesitate to post on Laracasts for help or here if you think you found an issue with Passport.
@mbm-rafal Are you by chance doing this in the web.php routes file or at the very least with the web middleware classes? The only way I was able to replicate what you're doing is by attaching the web middleware (or using the web routes file) to the route example you have shown above. Then the exception gets thrown because eventually it's trying to decrypt the laravel_session cookie, which of course won't work. Please let me know and hopefully we will be closer to resolving the problem.
@craigpaul -- just to follow up, I recently upgraded our application from Laravel 5.2 to 5.3. As an interim step, I had to use web middleware on our API routes. After adding the HasApiToken trait to the User and switching our API routes back to using the api middleware, our application is now fully operational. Appreciate the quick responses!
@craigpaul
Yes, actually I'm creating token through route that has 'middleware' => ['auth:api'] my Kernel's config for api.php routes
'api' => [
\App\Http\Middleware\EncryptCookies::class,
\Illuminate\Session\Middleware\StartSession::class,
\Laravel\Passport\Http\Middleware\CreateFreshApiToken::class,
'bindings',
],
but I do not understand how does it event try to decrypt laravel_session cookie while I am setting it directly to the encrypter ?
I've tryied to disable EncryptCookies mdlwr but with no luck.
@mbm-rafal oh man, never even thought about this, but you're not encrypting your "cookie" because it's not being sent as a cookie, it's being sent in the JSON so of course it doesn't work. If you encrypt the $cookie->getValue() then it would return the proper array. Now all that being said, I think you might want to rethink how you are trying to use this.
The CreateFreshApiToken middleware definitely is useless under API routes as it only attaches cookies to instances of Illuminate\Http\Response, but in your case, you're sending an Illuminate\Http\JsonResponse instance. If you really need to go this route, I suppose you could just encrypt the $cookie->getValue() and send that. Either way, I don't think this is really an issue with Passport, we should probably close this and move the convo to Laracasts.
@craigpaul you had right! After encrypting cookie value before pushing result did the job!
Anyways. I'm surprised that you're surprised how I'm using this for my case by using laravel as a microservice for frontend components.
This way or another. We can finally close this issue. @craigpaul thank for your assistance! Really appricieate that!
@mbm-rafal Not a problem, and would you mind closing the issue? Only the OP and repo admins can close issues :)
@mbm-rafal any solution for this case. I'm facing same issue.
dd($payload, base64_decode($payload), json_decode(base64_decode($payload), true));
$payload - is fine
base64_decode($payload) - is fine
json_decode(base64_decode($payload), true) -- is null
So shouldReceiveFreshToken always return false
Any solution please? - fixed
I didn't add \App\Http\Middleware\EncryptCookies::class at api
take a loot @ this topic https://laracasts.com/discuss/channels/laravel/jwt-invalid-payload
Most helpful comment
@craigpaul -- just to follow up, I recently upgraded our application from Laravel 5.2 to 5.3. As an interim step, I had to use
webmiddleware on our API routes. After adding theHasApiTokentrait to the User and switching our API routes back to using the api middleware, our application is now fully operational. Appreciate the quick responses!