AJAXポストリクエストをLaravel APIに送り返し、このエラーメッセージを受信しています。
compiled.php 13235行のDecryptException:ペイロードが無効です。
CookieからXSRF-TOKENを読み取り、X-XSRF-TOKENという名前のリクエストヘッダーとして送信します。
このサイトはLaravel APIから完全に独立したサイトですが、同じセッションを共有しているため、Cookieから値を取得しています。
奇妙なことは、ときどき機能することです。何がこれを引き起こしているのでしょうか?
JavaScriptから_X-XSRF-TOKEN
_を送信する場合は、decodeURIComponent()
を使用してデコードできます。 _%3D
_を_=
_に変換します。
私は問題の原因を見つけました。 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;
}
同様の問題がありましたが、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ステートメントは常に成功します。リクエストヘッダーのデータ量に関連しているようですが、問題は非決定的です。