はじめに
私自身、『セッション(session)ついて人から質問された際に、納得してもらえるような説明ができるぐらい理解を深めたい』という思いから今回の記事を書くことにしました。
記事の中に間違いがありましたらご指摘いただけると幸いです。
そもそもセッションとは
セッションについては既にQiitaさんに沢山の素晴らしい記事が投稿されていますが、個人的に以下の記事がわかりやすいと思いました。
セッションについてはクッキーとセットで使われることが多いと思いますが、今回クッキーについての詳細な説明は割愛させていただきます。
セッションはどういった機能を実現するために使用されるか
セッションが使われている具体例として、以下が挙げられます。
- ユーザー認証
- カートの管理
- フォームから送信されたデータの保持
- バリデーションのエラーメッセージ
上記以外にも様々な使用場面が考えられます。
今回は上記の中からユーザー認証をピックアップし、どのような流れでセッションが使用されているかを確認し、セッションについての理解を深めたいと思います。
ユーザー認証の流れ(ログイン状態の有無、ログアウトも含む)
一般的なMPAアプリケーション(Multi-Page Application)において、セッションを使ったユーザー認証(1、2、3、4、5)、ユーザーのログイン状態の有無確認(6、7)、ログアウト(8)の流れが以下になります。
1. ユーザーがアプリケーションにアクセスして、ログインページに飛ぶ。
2. ユーザー名とパスワードを入力してログイン。
3. 入力された情報はサーバーに送信され、サーバー側でユーザー認証が行われる。
4. サーバーはユーザー名とパスワードの組み合わせを確認し、認証が成功した場合はセッションを作成、セッションIDをクッキー(cookie)を通じてブラウザに保存。
5. ユーザーは認証が成功したことを示すメッセージを受け取る。
6. ユーザーがアプリケーション内の別のページに移動するたびに、ブラウザはセッションIDをサーバーに送信。
7. サーバーは受け取ったセッションIDを使用してセッションを特定し、ユーザーの認証状態を確認。
8. ユーザーがログアウトする場合、サーバーはブラウザに保存されているセッションIDを削除し、サーバー側のセッションデータも削除する。
上記の中で、セッションが出てくる個所(4、7、8)をコードも交えて補足説明していきます。それ以外の個所はセッションがPHP側のコードに含まれないので割愛させていただきます。
4. サーバー側でのユーザー認証とセッション情報を保存
<?php
session_start();
// ログインフォームから送信されたユーザー名とパスワードの取得
$username = $_POST['username'];
$password = $_POST['password'];
/* ユーザー名とパスワードの検証
(仮の条件として、ユーザー名が "admin"、パスワードが "password" であると認証。
本来はDBにユーザー名を問い合わせ、ユーザーが存在した場合、ハッシュ化されたパスワードと比較を行う)
*/
if ($username === 'admin' && $password === 'password') {
// 認証成功時の処理
// セッションにユーザー情報を格納
$_SESSION['username'] = $username;
// セッションIDをクッキーに保存
$sessionId = session_id();
setcookie('PHPSESSID', $sessionId, time() + 3600, '/');
// ログイン後のリダイレクトなどの処理
header('Location: dashboard.php');
} else {
// 認証失敗時の処理
echo 'ユーザー名またはパスワードが間違っています。';
}
?>
このコードでは、ユーザーがログインフォームから送信したユーザー名とパスワードを検証し、認証が成功した場合にセッションにユーザー情報を格納し、セッションIDをクッキーに保存します(setcookie関数を使用)。ログイン成功後は、header関数を使用してリダイレクトなどの適切な処理を行います。
このようにセッションを使用してユーザー情報を保存することでページ遷移の際に、ユーザーのログイン状態の有無を確認できるようになります。
7. セッションを特定し、ユーザーの認証状態を確認。
<?php
session_start();
// ログインしているユーザーかどうか判定
if (isset($_SESSION['username'])) {
// ログインユーザーだと証明されたのでtrueを返却。
return true;
} else {
// ログインしていないユーザーの場合の処理
header('Location: login.php');
exit();
}
?>
このコードは主にページ遷移した際に、ログインしているユーザーのみにページ表示させる場面で使用されます。ユーザーがログインしている場合は処理を続行し、ログインしていない場合はログインページにリダイレクトすることで、認証の要件を満たさないユーザーを制御します。
8. ログアウトを行い、ブラウザとサーバーのセッション情報を削除。
<?php
session_start();
// セッション変数を全て解除する
$_SESSION = array();
// セッションを切断するにはセッションクッキーも削除する。
// Note: セッション情報だけでなくセッションを破壊する。
if (ini_get("session.use_cookies")) {
$params = session_get_cookie_params();
setcookie(session_name(), '', time() - 42000,
$params["path"], $params["domain"],
$params["secure"], $params["httponly"]
);
}
// 最終的に、セッションを破壊する
session_destroy();
// ログアウト後のリダイレクト処理
header('Location: login.php');
?>
このコードはセッションを破棄し、ユーザーをログアウトさせる際に使用されます。セッション変数を解除し、セッションクッキーを削除してセッションを無効化し、最後にセッションを破壊します。ログアウト後には指定されたページにリダイレクトされます。
上記のコードはPHPのドキュメントに記載されている、セッションを破壊するコードとほぼ一緒です。参考までにURLを下記に貼っておきます。