質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

88.62%

phpにおけるセッション破棄の使い方について

解決済

回答 2

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 1,184

hatsuzo

score 26

度々お世話になっております。
phpによる基礎的なセッションタイムアウトの方法について
で質問させて頂いた者です。

一定時間が経過後にタイムアウトを行わせる画面遷移を考えておりますが、アドバイスを頂いたおかげで、基本的な流れを作るところまで辿り着きました。考え方はこうです。
<画面A>
セッションが無い時は作成し、開いた時間をセッション変数(t)にSAVE
セッションがある場合は、開いた時間をセッション変数(t)と比較して、一定時間経過後に画面Bに遷移させる。
<画面B>
セッションの削除
エラーメッセージを表示してボタン押下時に画面を閉じる

基本的にはこの画面でほぼ動作することを確認しましたので、最終的には、各画面に<画面A>と同じチェック処理を入れることを考えています。

確認の動作としては、

  • <画面A>で一定時間後に、画面をリロードすると、<画面B>に遷移
  • <画面B>でスクリプトを閉じる操作をした時、フォームは閉じるが、空白の画面が残る。
  • 再度、<画面A>を呼び出した時も、同じ動作になる
    ことを確認しました。

ただ、この時、<画面B>の状態でブラウザの戻るボタンを押すと、<画面A>に戻ってしまうため、それを防止するため、

window.onunload = function(){};
history.forward();


と入れたところ、<画面A>に戻らなくなったので、無事解決となりました。
ところが、<画面A>のURLを呼び出したところ、<画面A>の処理の中で、セッションが残っている状態、つまり、(if(isset($_SESSION['LOGIN_INFO'])))と判定され、自動的に<画面B>に遷移する動きになってしまいました。

再度呼び出しても同じなのですが、<画面B>で戻るボタンを一度押した状態で、<画面A>を呼び出したところ、呼び出せることが判ったのですが、解決策が見つからなく困っております。

おそらくセッションの解放のしかたに問題があるのではないかと思うのですが、識者のアドバイスを頂ければ幸いです。

PC側の実行環境は、Windows10で、ChromeとFirefoxでこの状況になります。IE11だとフォームを完全にクローズするため、この現象は出ません。

<画面A>
<?php
    if( !isset( $_SESSION ) ) {
        session_start();
    }
    // セッションが存在していない(タイムアウトもしくはログアウトされている)
    if(!isset($_SESSION['LOGIN_INFO'])) {
        $_SESSION['LOGIN_INFO'] = true;
        $_SESSION['LAST_TIME'] = date("Y-m-d H:i:s");
    // セッションが存在している場合はセッションのライフタイムを更新
    } else {
        $_SESSION['LOGIN_INFO'] = true;
        $last_tm = $_SESSION['LAST_TIME'];
        $_SESSION['LAST_TIME'] = date("Y-m-d H:i:s");
        print "last:{$last_tm}<br />";
        print "now:{$_SESSION['LAST_TIME']}<br />";
        // 時刻差(秒数)
        $diff_min = (strtotime($_SESSION['LAST_TIME']) - strtotime($last_tm));
        if ($diff_min > 5){
            echo "<script> window.location.replace('ss_timeout.php'); history.pushState(null, null, null); </script>"; 
        }
    }
    echo "<br /><a href='sess02.php'>サンプル画面2へ</a>";
?>
<画面B>
<html>
<head>
<script language="JavaScript">
<!--
window.onunload = function(){};
history.forward();
//-->
</script>
</head>
<body>
<?php
// セッションの切断
if( isset( $_SESSION ) ) {
    $_SESSION = array();
    if (isset($_COOKIE["PHPSESSID"])) {
        setcookie("PHPSESSID", '', time() - 1800, '/');
    }
    session_destroy();
}
?>
<div>
    <p>長時間使用されていないため、タイムアウトが発生しました。</p>
    <p>「閉じる」ボタンをクリックして終了して下さい。</p>
    <p><div align="center"><a href="javascript:window.open('about:blank','_self').close();">閉じる</a></div></p>
</div>
</body>
</html>
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 2

checkベストアンサー

0

ちょっと質問の主旨が理解できていませんが、session の取扱を理解していないように思います。

ざっと気になった点を羅列します。
・$_SESSION を使用するのであれば、それより前に session_start() が必要です。
・time-out の処理の中で、$_SESSION['LOGIN_INFO'] の中身を変更していないので、true が残り続けています。

いわゆるログアウトの処理になると思いますので、ログアウト機能の目的と実現方法 を参照の上、実装すると良いです。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/06/20 18:48

    画面B で session 破棄をしようとしているんですかね?
    であれば、1番目の項目だけ見ればよいかと。
    個人的には、画面 A の time-out 処理の中でログアウトさせたいですけど。

    キャンセル

  • 2019/06/21 14:39

    コメントありがとうございます。

    if( !isset( $_SESSION ) ) {
    session_start();
    }
    の部分は実は私もよく理解せず、ネット上のサンプルを見て使っていましたが、確かにセッションが無い時はエラーになりますので変ですね。

    $_SESSION['LOGIN_INFO'] をその後、特に使う必要も無ければ、単純に$_SESSION['LAST_TIME']の有無だけでセッションの継続の判断をすればよいということですね?

    確かにそこでさせても問題ないですね。
    何れにしても、戻るキーでの所作を止める必要はあるかと思いますので、そこでちょっと行き詰っています。IEの場合は問題ないのですが、Chromeで戻るキーを止めるのはなかなかうまくいきませんが、セッションの考え方とは別問題、ということのようですね。
    戻るキーを押した時は、当然画面のリロードはされない訳なので厄介ですね。

    キャンセル

0

<画面A>
セッションが無い時は作成し、開いた時間をセッション変数(t)にSAVE
セッションがある場合は、開いた時間をセッション変数(t)と比較して、一定時間経過後に画面Bに遷移させる。

そもそもプログラム側でセッション時間比較せずとも、セッション有効期間の設定でセッション値が取れなくなるので不要です。
画面を最初に開いた時からの経過時間を制限したい場合は、クッキーの有効期間で制御します。

session.cookie_lifetime
ブラウザにセッションIDのCookieを発行する際のCookieの有効期限。
ブラウザはこの期限を過ぎるとCookieを破棄するので、結果としてセッションが途切れることになる。
デフォルトは0で"ブラウザを閉じるまで"という意味。

session.gc_maxlifetime
サーバに保存されているセッションファイルを保護する有効期限。
セッションデータそのものの有効期限ではないし、そのような設定項目はない。
リロードされないまま有効期限を過ぎたら、その後セッションファイルが削除される可能性がある。

session.gc_divisor
session.gc_maxlifetimeを過ぎると必ずセッションファイルが削除されるわけではなく、PHPにリクエストがあったときに(session.gc_probability / session.gc_divisor)の確率でGCが起動して実際に削除される。
セッションファイルそのものには有効期限は書かれていないため、session.gc_maxlifetimeを過ぎてもGC起動前であればセッションデータにアクセス可能。
デフォルトはsession.gc_probability=1、session.gc_divisor=100で、1%の確率でGCが起動する。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/06/21 19:17

    でも、元になる時間が必要か^^;失礼。やっぱり制御できないと思います。

    キャンセル

  • 2019/06/21 19:57

    おっしゃる通りクッキーはクライアントに依存するので、厳密に時間をコントロールするのでしたらセッション管理が良いですね。

    キャンセル

  • 2019/06/24 19:17

    hide0128さん コメントありがとうございます。
    ちょっと私には理解できないレベルになってしまいました。
    セッションはログインからログアウトに至るまでの間の時間を意味するものという理解だったので、その有効期限は全体の寿命を表すものであって、セッション内部での一つ一つの画面遷移の経過時間を取るのになぜセッションの有効時間を使うのか理解に苦しみます。
    もう少し理解が深まったらもう一度考え直してみようと思いますが、ひとまず、セッション変数を使ってその値をCookieに保存して、という当初の方法で実装しようと思います。
    有難うございました。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 88.62%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る