Laravel DecryptException - The payload is invalid
I found out the cause of the problem. The XSRF-TOKEN cookie value sometimes had a rogue character appended to the end: '%3D' - sometimes there are two of these on the end. No idea how they get there but when they are present, the verification fails.
If you base64_decode the cookie value, you get a json string which has the rogue character: '7' appended to the end so Laravel's decrypt method fails.
I ended up having to write my own CSRF verify function:
$payload = base64_decode($request->header('X-XSRF-TOKEN')); //Remove any rogue chars from the end of the json for($i=0; $i<strlen($payload); $i++){ $lastChar = substr($payload, -1); if($lastChar != '}'){ $payload = substr($payload, 0, -1); } else { break; } } //Needs to be base64 encoded when passed to decrypt $payload = base64_encode($payload); $headerToken = decrypt($payload); $cookieToken = $request->cookie('XSRF-TOKEN'); //Compare tokens if($headerToken == $cookieToken){ return true; } else { return false; }
I had the same issue and it was indeed due to the cookie being url encoded and not decoded correctly by laravel
You can solve it by url decoding the cookies before decryption
in app/Http/Middleware/EncryptCookies.php
<?phpnamespace App\Http\Middleware;use Illuminate\Cookie\Middleware\EncryptCookies as Middleware;class EncryptCookies extends Middleware { /** * Decrypt the given cookie and return the value. * * @param string $name * @param string|array $cookie * @return string|array */ protected function decryptCookie($name, $cookie) { return is_array($cookie) ? $this->decryptArray($cookie) : $this->encrypter->decrypt(urldecode($cookie), static::serialized($name)); }}
Make sure you are using the correct middleware in app/Http/Kernel.php
, you should look for EncryptCookies
and replace it with the new class
Eg:
protected $middlewareGroups = [ 'web' => [ \App\Http\Middleware\EncryptCookies::class, //...