web-dev-qa-db-ja.com

Laravel DecryptException-ペイロードが無効です

AJAXポストリクエストをLaravel APIに送り返し、このエラーメッセージを受信して​​います。

compiled.php 13235行のDecryptException:ペイロードが無効です。

CookieからXSRF-TOKENを読み取り、X-XSRF-TOKENという名前のリクエストヘッダーとして送信します。

このサイトはLaravel APIから完全に独立したサイトですが、同じセッションを共有しているため、Cookieから値を取得しています。

奇妙なことは、ときどき機能することです。何がこれを引き起こしているのでしょうか?

5
ezero

JavaScriptから_X-XSRF-TOKEN_を送信する場合は、decodeURIComponent()を使用してデコードできます。 _%3D_を_=_に変換します。

8
VnoitKumar

私は問題の原因を見つけました。 XSRF-TOKEN Cookieの値には、末尾に不正な文字が追加されている場合があります: '%3D'-末尾にこれらの2つがある場合があります。彼らがどうやってそこにたどり着くのか分かりませんが、彼らがいると、検証は失敗します。

Cookie値をbase64_decodeすると、不正な文字「7」が末尾に追加されたjson文字列が取得されるため、Laravelの復号化メソッドは失敗します。

私は自分でCSRF検証機能を書く必要がありました:

$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;
            }
3
ezero

同様の問題がありましたが、Google Chromeのみに関連しているようです。復号化例外が発生した場合は、EncryptCookiesをdd()に変更しました。

protected function decrypt(Request $request)
{
    foreach ($request->cookies as $key => $c) {
        if ($this->isDisabled($key)) {
            continue;
        }

        try {
            $request->cookies->set($key, $this->decryptCookie($c));
        } catch (DecryptException $e) {
            dd('exception: ', $e, $key, $c, $request); // added by me
            $request->cookies->set($key, null);
        }
    }

    return $request;
}

奇妙なことに、ページを更新するたびに、DecryptExceptionがスローされることがありますが、ほとんどの場合、tryステートメントは成功します。 IEとFirefoxでテストすると、tryステートメントは常に成功します。リクエストヘッダーのデータ量に関連しているようですが、問題は非決定的です。

0
Andy White