そもそもHTTP通信とは
HTTP通信はステートレスなプロトコル(通信手段)として確立しています。
ステートレス、とはサーバーは1回1回の通信で完結しており、以前の通信の結果を記憶していません。
だからこそ、HTTPはシンプルで強靭なプロトコルであり続けています。
例えば、何も処理をしていなければ、
- ユーザーからサーバー(PHP)にログインのリクエストを送る
- サーバーはチェックを行い、ログイン完了の返事をする
- ここで通信は終わるので、ユーザーが通信した記録は残らない
- 再度通信しても、ログインを求められる
そのため、ログインした状態をサーバーに覚えさせておきたい場合、 セッション という仕組みを利用します。
セッションを使う
Webページを開いてから閉じるまでを1セッションとし、その間情報を保存しておきます。
実際に使用したソースコードを見てみましょう。
ログイン画面、ログアウト画面で作成した、login.php
を開いてください。
まず、セッションを使用する宣言をします。
// セッション開始 session_start();
その後、ログイン処理を実施していきますが、入力されたパスワードとDBに保存されたパスワードが一致したら、下記のように セッション変数 に保存しています。
// セッションに値を保存 $_SESSION['user_id'] = $row['id']; $_SESSION['user_name'] = $row['name'];
これで、ログイン完了し、通信が終了したとしても、セッションに値は残ります。
今回は、ユーザーのIDと名前をセッションに保存しておきます。
セッションに値があるか確認
次に、main.php
です。
このメインページはログインしていなければ、アクセスさせたくないです。
ログインしているということは、 セッション変数に値が入っている ということです。
そのため、ページロード時に下記の条件判定を行います。
もし、セッションに値が入っていなければ、ログインしていないということ なので、header
関数でログインページに戻してしまいます。
// セッション開始 session_start(); // セッションにuser_nameの値がなければlogin.phpにリダイレクト if (empty($_SESSION["user_name"])) { header("Location: login.php"); exit; }
ログインチェックの関数化
上記の「セッション変数に値がない(ログインしていない)場合は、ログインページに戻す」処理は、その他のページでも使用しそうです。
そのため、db_connect.php
と同様に関数にしましょう。
function.php
というファイルを作成し、そこに移設します。
<?php // function.php /** * $_SESSION["user_name"]が空だった場合、ログインページにリダイレクトする * @return void */ function check_user_logged_in() { // セッション開始 session_start(); // セッションにuser_nameの値がなければlogin.phpにリダイレクト if (empty($_SESSION["user_name"])) { header("Location: login.php"); exit; } }
関数としてひとまとめにしたので、main.php
も下記のように修正しましょう。
(FILL_INの部分は自分で埋めてください。)
<?php // function.phpの読み込み FILL_IN // ログインしていなければ、login.phpにリダイレクト check_user_logged_in(); ?> <!doctype html> <html> <head> <meta charset="UTF-8"> <title>メイン</title> </head> <body> <h1>メインページ</h1> <p>ようこそ<?php echo $_SESSION["user_name"]; ?>さん</p> <a href="logout.php">ログアウト</a> </body> </html>
ログアウトしてセッションに保存されている値を破棄する
ログインというのは、セッションに値があるかどうかで判定しています。
言い換えれば、セッションから値をなくせば、ログイン状態を解除できます。
ログアウトではまさにそのような処理を行っています。
<?php // セッション開始 session_start(); // セッション変数のクリア $_SESSION = array(); // セッションクリア session_destroy(); ?>
- セッションの中にある全ての変数を初期化(空の配列にしてしまう)
session_destroy
メソッドで、セッションを完全にクリアする
この手順はPHPの公式リファレンスにも記載されています。
また、ログアウトするときは基本的にこの手順で問題ありません。
さいごに
さて、セッションについて見てきましたが、実際にWebブラウザを閉じて再度開いても、ログイン状態は保持されていると思います。
これはCookieという仕組みを利用しています。
(今回の研修では省略します。)
また、セッションは非常に便利ですが、セッションハイジャックと呼ばれるセキュリティ的な脆弱性も存在します。
そのため、過信は禁物であり、実際に自分のコンテンツで利用する場合は調査を念入りに実施してください。