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

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

新規登録して質問してみよう
ただいま回答率
85.48%
PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

Q&A

解決済

2回答

7150閲覧

php 自動ログアウトについて その2

beginner_39

総合スコア77

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

0グッド

0クリップ

投稿2017/09/20 04:14

編集2017/09/20 04:33

再度質問。。。
前回ご協力いただきましたユーザー様、誠にありがとうございます。

色々ためした結果、思うように動作できなかったので、
再度自分の頭をリセットする意味で質問させていただきます。

###現在の各ページのコード
↓各ページの冒頭記述↓

<?php require 'password.php'; session_start(); // ログイン状態のチェック if (!isset($_SESSION["USERID"])) { header("Location: logout.php"); exit; } ?> ※※※※ ここからhtmlコード

###ログアウトphpコード

<?php session_start(); if (isset($_SESSION["USERID"])) { $errorMessage = "ログアウトしました。"; }else{ $errorMessage = "ログイン情報を確認し、ログインしてください。"; } session_destroy(); ?> ※※※※ ここからhtmlコード

###補足事項
php.iniファイルはあるが、特に設定はしておりません。
→設定していない理由は、現在wordpressを使用して自社サイトを持っており、
wordpressもログイン画面があるが、一定操作が行われなかったら自動ログアウトになるため、
php.iniファイルは特に触っておりません。
むしろ、php.iniはあまり関係ない?と思っております。
php.iniを設定しなくても自動ログアウトコードは作れるのでは?と感じています。

上記記述しているphpコード(ログイン画面等)はwordpressとは関係ない別ディレクトリに作成しています。
→理由としては、wordpressに影響しない完全なるシステムページを作るため。

###できなかったこと

ini_set( 'session.gc_maxlifetime', 60 ); // 秒(デフォルト:1440)

の時間設定を行っても、自動ログアウトなりませんでした。
また、試しにphp.iniにも「session.gc_maxlifetime」を設定してもうまく動作できず。
さらに、今現在はissetの中を「$_SESSION["USERID"]」に設定しておりますが、$_SESSION['LOGIN_INFO']にすると、

<p>ようこそ<?=htmlspecialchars($_SESSION["USERID"], ENT_QUOTES); ?>さん</p>

のUSERIDが表示もされず「ようこそさん」になります。

###質問したいこと
①上記を踏まえてphp.iniの設定は必要なのか?
②時間設定の仕方は間違っているのか?
②-1.時間設定はクッキー?セッション?両方を削除しないと動作されない仕様なのか?
③むしろif分岐がそもそも間違って動作されているのか?

セッション及びクッキーの設定がいまいち理解できていないので、教えていただきたいです。
長文になりましたが、ご教授願います。

どうぞよろしくお願い致します。

気になる質問をクリップする

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

m.ts10806

2017/09/20 04:18

プログラムコード(およびエラーメッセージ)は```で囲ってください。(わからなければ質問編集画面でコード部分を選択し<code>ボタンを押してください)
beginner_39

2017/09/20 04:21

mts10806様 ご指摘ありがとうございます。修正させていただきました。
m.ts10806

2017/09/20 04:21

「質問したいこと」が書いてないように思います。聞きたいことを明記してください。また「思うように動作できなかった」とは何が起きたのでしょうか?「○○となるはずだ(△△したい)けど、××のようになった」という形で記載してください。
beginner_39

2017/09/20 04:34

mts10806様 お騒がせしました。自分も現在頭の中が整理できずうまく質問ができないでおりますが、少しづつ整理して修正させていただきました。よろしくお願いいたします。
guest

回答2

0

ベストアンサー

phpのセッション管理はちょっと分かりにくいですよね。
私も学生時代混乱しました。

①上記を踏まえてphp.iniの設定は必要なのか?

必要です。
session.gc_maxlifetimeはログイン有効時間以上にする必要があります。

②時間設定の仕方は間違っているのか?

間違ってはいません。
ただ、ブラウザのクッキー有効期限を間違えている可能性があります。

②-1.時間設定はクッキー?セッション?両方を削除しないと動作されない仕様なのか?

どちらかを消せば非ログイン状態となります。
セッションファイルの削除はphpに任せ、session_destroy()を実行するだけでokです(なのでファイルが残る場合もあります)。
問題はクッキーの有効期限です。
一般的にこちらを削除して(有効期限を設定して)、ログイン/非ログイン状態としています。
beginner_39さんが書かれたコードの中で、セッションを生成するときにsetcookie()という関数を実行しているところがあるはずです。

setcookie("test", $sessionId, time() + 3600);

この第3引数がクッキーの有効期限で、上の例では1時間にしています。
クッキーが残っている=サーバに渡すセッションIDがあるため、ログイン判定可能としているわけです。

③むしろif分岐がそもそも間違って動作されているのか?

間違っていませんが、USERIDだけでは不十分です。
ユーザがクッキーを直接書き換えてセッションIDを偽装した場合、ログインできてしまう可能性があるからです。
最終ログイン時間もセッションに入れておき、ログイン有効期限内か判定してあげましょう。

if (!isset($_SESSION["USERID"]) and time() - $_SESSION["LAST_LOGIN"] > 3600) { //ログアウト処理 exit; }

まとめると、基本的なログイン状態の判定は3つの要素で行われます。

  • セッションファイル
  • クッキー
  • 最終ログイン時間

最終ログイン時間は最終アクセス時間としてもokです。

投稿2017/09/20 06:56

ooeok

総合スコア469

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

beginner_39

2017/09/20 07:45 編集

ooeok様 お忙しい中、貴重な時間を割いてご回答いただき大変感謝申し上げます。 とても丁寧なご回答で少しづつ整理ができそうです! ご回答いただきましたが、追加のご質問です。 ※※※※※※ setcookie("test", $sessionId, time() + 3600); ※※※※※※ のような「setcookie」の記述を探してみたのですが、記述がありませんでした。 もしない場合は、ログアウトphpに記述した方がいいのでしょうか? それとも各ページごとに記述した方がいいのでしょうか?
ooeok

2017/09/20 08:02 編集

それでは、ログイン処理にこんな記述はありませんか? ・ setrawcookie() ・ header("Set-Cookie: session_id=***"); クッキーを使っているならこの手の記述があるはずです。
beginner_39

2017/09/20 08:25

ooeok様 見当たらなかったです。 今回作成したログインシステムはネットにある文言を使用しながら作りました。。。 もしかしたらcookieそのものの設定ができていないのかもしれないと感じました。 不正?とまではいきませんが、ミスがありすぎるプログラムになっているかもしれません。 少し見直します。。 ちなみにですが、教えていただきました 「setcookie("test", $sessionId, time() + 3600);」のような記述は基本的にはどのページに記載するのが正しいのでしょうか?
ooeok

2017/09/20 08:56

ということは、session_start()で暗黙的にcookieを使ってるようですね。 php.iniのsession.cookie_lifetimeがクッキーの有効期限になります。 session_start()で勝手にクッキーを設定してくれるので、ログイン時にsetcookie()は必要ありません。 ログイン時には、ログイン(アクセス)時間だけセッションに入れておけばokです。 setcookie()はログアウト時にクッキーを破棄するのに使います。 session_destroy()の前に入れましょう。 setcookie(session_name(), '', time() - 42000); session_destroy();
beginner_39

2017/09/20 09:17

ooeok様 自動ログアウト設定、できました!とても感謝です!ありがとうございます! 最後に2点ほど確認させていただきたいのですが、 ①ログイン時には、ログイン(アクセス)時間だけセッションに入れておけばokです。 →セッションに入れておくというのはどのようなことでしょうか? ②session.cookie_lifetimeを設定したら動作できました。 ちなみに下記3つの記述も必要になってくるのでしょうか? そのまま記述してた方が良いのでしょうか? session.gc_maxlifetime session.gc_probability session.gc_divisor
ooeok

2017/09/20 12:20

プログラムとしては以下のように書くだけです。 $_SESSION["LAST_LOGIN"] = time(); gc_probabilityやgc_divisorなどはデフォルトがあるので、必要なければ特に設定する必要はありません。 http://php.net/manual/ja/session.configuration.php
beginner_39

2017/09/21 01:12

ooeok様 いろいろと大変助かりました!いただいたURLを参照させていただき、勉強させていただきます。 今回はお時間を割いていただき誠にありがとうございました。 取り急ぎ、お礼までのコメント。
guest

0

確か、PHPにおけるphp.iniでのセッションのガーベージコレクト設定って、設定した時間が来たら必ず破棄されるわけじゃないっすよ。
実行時設定

gc_maxlifetimeに設定した時間で破棄対象になることはなるんですが、その判断タイミングが誰かのセッション開始なので、誰もアクセスしてこないとサーバーには永遠に残ってます。

で、gc_probabilityが破棄確率分子でデフォルトが1、gc_divisorが破棄確率の分母なのですが、こいつはデフォルトが100で、つまり、上記破棄タイミングにデフォルトでは100分の1の確率で破棄される、という仕様だったと思います。

だからまぁ、gc_divisorを1に設定したら、時間が来て誰かがセッションを開始した時確実に破棄されることになるのかなぁ? やったこと無いですけど。

誰かがアクセスしてくるまでは一生セッション残ってる仕様のはずなので、確実にサーバーから消すにはそれこそ、cron走らせて定期的にセッションを開始するのがいいのかな。

あとはまぁ妥協策として$_SESSIONに前回アクセス時刻を保持しておいて、プログラム的に時間を超えていたら強制的にdestroyしてログアウトですね。結局、誰かがアクセスしてくるまでは一生セッション残ってますけど。

たしか、そんな感じのはずです。

投稿2017/09/20 05:06

編集2017/09/20 05:09
退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問