INASOFT 管理人のひとこと


フリーソフトダウンロードサイト「INASOFT」の管理人 矢吹拓也 が日々の「ひとこと」を語るページです。
2021年1月1日より、旧ブログ(blog.inasoft.org)からお引越ししました。
・INASOFT Webサイト: https://www.inasoft.org/
・管理人のふたこと(長文記事/寄稿文): https://www.inasoft.org/talk/
本業の方のお仕事が再び忙しくなりつつあるので、断続的にしばらく更新が止まることがあります。

目次 | ←前へ / 2014-08-28 00:00 / 次へ→ / 最新へ⇒

■JavaScriptで設定したクッキーってPHPで読み込めないのかな?

2014/ 8/28 0:00:00


RSSRSS配信中

https://www.inasoft.org/








【追記あり:後半(続きを読む)以降に、犯人候補(さくらのレンタルサーバのコントロールパネルにある、Webアプリケーションファイアウォール(WAF)のJP-Secureの「SiteGuard」の件)に触れています】

クッキーの実験をしてみようと思い、次のような簡単なプログラムを組んでみました。

<HTML>
<HEAD>
 <TITLE>クッキー実験場</TITLE>
</HEAD>
<BODY>
<?php
$val = $_COOKIE["test1"];
echo '[php]:test1='.$val.'<br><br>';
echo '[php]print_r($_COOKIE)=';
print_r($_COOKIE);
echo '<br><br>';
?>

<script language="javascript">


document.writeln("[js]:test1='"+getCookie("test1")+"'<br><br>");

setCookie("test1","value1",7);

document.writeln("[js]:test1='"+getCookie("test1")+"'<br><br>");

function setCookie(c_name,value,expiredays){
    // 有効期限の日付
    var exdate=new Date();
    exdate.setDate(24*60*60*1000*expiredays);
    // クッキーに保存する文字列を生成
    var s="";
    s+=c_name+"="+escape(value);
    s+=(expiredays==null)?"":"; expires="+exdate;
    // クッキーに保存
    document.cookie=s;
}


function getCookie(c_name){
    var st="";
    var ed="";
    if (document.cookie.length>0){
        st=document.cookie.indexOf(c_name + "=");
        if (st!=-1){
            st=st+c_name.length+1;
            ed=document.cookie.indexOf(";",st);
            if (ed==-1) ed=document.cookie.length;
            return unescape(document.cookie.substring(st,ed));
        }
    }
    return "";
}

</script>

</BODY>
</HTML>


まず1回目の実行では、値を書き込むだけなので、最後の[js]のところにだけ値が表示されるだろう事は予想しています。

結果はこんな感じ。

[php]:test1=

[php]print_r($_COOKIE)=Array ( )

[js]:test1=''

[js]:test1='value1'

2回目からは、全ての場所にvalue1が表示されるかなと思い、2回目の実行(リロード)をしてみると・・・

[php]:test1=

[php]print_r($_COOKIE)=Array ( )

[js]:test1='value1'

[js]:test1='value1'


1つ目の[js]には値が設定されているので、クッキーが有効になっていることは確かなのですが、どういうわけだか、[php]の方には何も表示されず…。

何度リロードしても結果は同じ。

これで4時間悩んだんですが、原因は分からず…。

JavaScriptとPHPのクッキーのやりとりって、相性が悪いとか、何かあるのかな?

ネット上で情報を調べると、世間ではこのような現象など一切起こらず、何の問題も無くやりとりされているようにしか見えないんだけど、なぜうちの環境でだけできないんだ!?

別にセッション管理をしたいとか、そんな大それたことをしようとしているわけでもないし。

Firefoxが悪いのかと思い、他のブラウザでも試したけど、IEでもSafariでもダメだし。

php.iniにクッキーを受け取らない(受け取れない)設定とかがあったりとかするのか?

うーむ、さっぱりわからん…。

誰か助けて。。。


【12:17 追記】そういえばこれの前段階として、PHPの中でのクッキー設定(setcookie関数を利用する方法)を試してうまく動いていたので、クッキーがあったときにブラウザに届かないとかサーバに届かないとかいうことはないみたいなんですね。

【8/29 追記】その後、期限日の設定の間違え等々、色々なアドバイスを頂いた内容を実践するも、うまくいかず。一方でTwitterからは、上の内容でもちゃんと動いているとの声しか届かない状態。つまり、ソースコードは推定無罪。

こうなると、ソースコードとの睨めっこは完全な的外れであり、さくらインターネットの設定との睨めっこの必要が出てきた。しかも犯人の名前すら掴めていない状態で…。

で、色々見ていたところ、犯人候補を発見。

waf.png

さくらのレンタルサーバのコントロールパネルにある、Webアプリケーションファイアウォール(WAF)。

JP-Secureの「SiteGuard」という製品なんだが、これの詳細を、実は分かっていないまま使っていた。

CGIの動作に影響がある旨はかかれているし、実際に、出力内容をキャッシュしていてサーバからブラウザに届く情報のリアルタイム性の一部が失われているというのは実感している。

そういえばPHPで設定したクッキーが、強制的にhttponlyにされてJavaScriptから読めないという別件の問題もあったし、今回JavaScriptから設定したクッキーをPHPから読めないというのも類似性を感じるし、WAFが中間に入ることで、クッキーのやりとりに問題を起こしているのではないか(やりとりさせないことを仕様としているのではないか)?

というわけで、犯人候補を見つけたところで今朝の調査時間は終わってしまったので、続きは次の土日で。

【続き】2014/8/31 ファイアウォールに食われてしまったクッキー


Posted by mlnms0i at 2014/08/28 08:08:38
chromeのデベロッパーコンソールで通信をキャプチャしてみてください

Posted by Ayacy at 2014/08/28 08:13:20
ありがとうございます。
帰宅したら早速試してみます。

…が、仮に送信電文の中に含まれていたとして(or いなかったとして)、その後のアクションは、難題ですね…。

Posted by みけCAT at 2014/08/28 08:20:50
Firefox31.0でalert(exdate)すると、Invalid Dateと出ました。
setDateに渡している値が明らかに大きすぎると思います。
例えばexpiredays日後にしたいなら、
exdate.setDate(exdate.getDate()+expiredays);
とするべきではないでしょうか?

Posted by Ayacy at 2014/08/28 12:09:07
ありがとうございます。修正して試してみます。

Posted by Ayacy at 2014/08/28 12:12:22
先ほど、Twitterの方で、記載の内容でも問題なく動いたという方がいらっしゃったので、ここまでの中では見えていない部分(PHPの設定かブラウザの設定かファイアウォール的なものか)に要因があると見るのが良さそうです。

Posted by mlnms0i at 2014/08/28 12:22:06
わかった
// 有効期限の日付
var exdate=new Date();
exdate.setDate(24*60*60*1000*expiredays);
// クッキーに保存する文字列を生成
var s="";
s+=c_name+"="+escape(value);
s+=(expiredays==null)?"":"; expires="+exdate;
// クッキーに保存
document.cookie=s;

の、 exdate.setDate(24*60*60*1000*expiredays); を
exdate.setTime(exdate.getTime() + 24*60*60*1000*expiredays); に変え、
s+=(expiredays==null)?"":"; expires="+exdate; を、s+=(expiredays==null)?"":"; expires="+exdate.toUTCString();
にしたら上手くいくかもしれない

参考:http://so-zou.jp/web-app/tech/programming/javascript/cookie/

Posted by Ayacy at 2014/08/28 12:42:59
ありがとうございます。
ただ、時刻のところは、いろいろ試してめちゃくちゃになった末に今の形になっただけでして、実際のところ、空にしても、特定の文字列をそのまま入れても、状況に変化がなさそうな状況ではあります。

Posted by みけCAT at 2014/08/28 17:02:03
いっそのこと有効期限の指定を消してみたらどうですか?
既に試しましたか?

Posted by Ayacy at 2014/08/28 21:05:14
そうですね。最初に試したのが、期限なしのパターンで、それがダメなのでいろいろ試していた感じです。

Posted by mlnms0i at 2014/08/28 22:04:25
もしかして:トラッキング拒否

Posted by Ayacy at 2014/08/28 22:20:08
なるほど。あのクッキー設定がトラッキングと誤認識されてしまった可能性ですね。
帰ったらIEとFirefoxの設定を見直しておきます。
iPhoneの設定にはあったかな…

Posted by Ayacy at 2014/08/28 23:37:00
帰宅したので色々試してみました。

ひとまず、Firebugでリクエストヘッダを調べてみたのですが、test1=value1という文字列は送られていました。

また、日付の設定を変えてみたのですがあ、状況は変わらず。

トラッキング設定については、特に通知設定は元々されていない状態だったので、無関係のようでした。

で、PHPスクリプト自体は、Twitter上で他の方から「自分の環境では動いた」という声が複数寄せられていることを考えると、どうやらレンタルサーバ側の設定(php.iniとか?)に、何かしらの要因があると見るのが妥当のような気がしてきました。次はそこを追ってみたいと思います。

皆様、ありがとうございました。

Posted by Ayacy at 2014/08/29 07:35:43
とりあえず、今朝は犯人候補まで分かって来たので、そこまでの情報をブログ本文に追記しました。


目次 | ←前へ / 2014-08-28 00:00 / 次へ→ / 最新へ⇒


目次の表示:


ブログではないので、コメント機能とトラックバック機能は提供していません。ご質問・ご意見等はメールフィードバックまたはTwitter等からお願いします。いただいたご質問・ご意見などは、この「管理人のひとこと」の記事に追加、あるいは新規の記事にする形で一部または全文をそのまま、あるいは加工させていただいた上で、ご紹介させていただく場合があります。
当サイトでは掲載内容による不具合等に関する責任を持ちません。また、内容の正確性についての保証もありませんので、情報をご利用の際は、利用者の自己責任で確認をお願いします。本ページは公開から1年半後の任意のタイミングで削除される予定です。




2561009 (+0156)[+0708]

Copyright© 2010-2021 INASOFT