はじめに: ログイン処理はWebアプリの基本機能
Webアプリでは、ログイン処理がよく使われます。管理画面、マイページ、会員向け機能、購入履歴など、本人だけが見られる画面にはログインが必要です。
ログイン処理は、単にメールアドレスとパスワードを送るだけの機能ではありません。フォーム送信、入力チェック、パスワード照合、セッション管理がつながって動いています。
HTTPは基本的に前のアクセス状態を覚えていません。そのため、ログインに成功したあとも、次のページで「この人はログイン済み」と判断するための仕組みが必要です。PHPでは、そのためにセッションを使います。
この記事では、PHPの短いサンプルを使いながら、ログイン処理の基本的な流れを整理します。実務用の完全なログイン機能ではなく、まずは「何をどの順番で確認しているのか」を理解することを目的にします。
ログイン処理は、入力された情報で本人確認を行い、成功した状態をセッションで管理する仕組みです。
ログイン処理は「認証」と「ログイン状態の保持」に分ける
ログイン処理は、大きく2つに分けると理解しやすくなります。
認証 → 入力された情報で本人かどうか確認する
ログイン状態の保持 → 認証済みであることを次のリクエストでも分かるようにする認証では、メールアドレスやユーザーIDをもとにユーザーを探し、入力されたパスワードが正しいかを確認します。
ただし、認証に成功しただけでは、次のページでもログイン済みだと分かるわけではありません。HTTPはステートレスなので、別のリクエストになると前回の結果を自動では覚えていないからです。
そこで、ログイン成功後にセッションへユーザーIDなどを保存します。次のリクエストでは、セッションにユーザーIDがあるかを見て、ログイン済みかどうかを判断します。
パスワードそのものをセッションに保存する必要はありません。ログイン状態を判断するには、ユーザーを識別できるIDなど、必要最小限の情報を保存すれば十分です。
ログイン処理は、本人確認をする処理と、ログイン状態を保つ処理に分けて考えると理解しやすくなります。
ログインフォームと入力チェック
まず、メールアドレスとパスワードを送るログインフォームを考えます。
<!doctype html>
<html lang="ja">
<body>
<form method="post">
<label>
メールアドレス:
<input type="text" name="email">
</label>
<label>
パスワード:
<input type="password" name="password">
</label>
<button type="submit">ログイン</button>
</form>
</body>
</html>フォームの値はPOSTリクエストとして送られます。PHPでは $_POST から受け取れますが、そのまま使う前に入力チェックを行います。
<?php
$email = trim($_POST['email'] ?? '');
$password = $_POST['password'] ?? '';
$errors = [];
if ($email === '') {
$errors[] = 'メールアドレスを入力してください。';
}
if ($password === '') {
$errors[] = 'パスワードを入力してください。';
}ログインフォームでは、メールアドレスとパスワードの必須チェックが基本です。メールアドレスの形式チェックを追加してもよいですが、ログイン処理では「そのメールアドレスが登録されているか」「パスワードが合っているか」という認証処理も必要になります。
エラーを画面に表示するときは、他のフォームと同じように htmlspecialchars() を使います。ユーザーが入力した値やエラーメッセージをHTMLに出すときは、表示時の安全性も意識します。
ログインフォームでも、受け取った値はそのまま使わず、まず入力チェックを行います。
パスワードはハッシュ値で照合する
実務では、パスワードを平文のまま保存しません。データベースの内容が漏えいしたとき、パスワードがそのまま読めてしまうからです。
ユーザー登録時には、入力されたパスワードを password_hash() でハッシュ化し、そのハッシュ値を保存します。
<?php
$passwordHash = password_hash('secret123', PASSWORD_DEFAULT);ログイン時には、入力されたパスワードと保存済みのハッシュ値を password_verify() で照合します。ハッシュ値から元のパスワードを復元するわけではありません。
学習用に、保存済みユーザーを配列で用意した例を見てみます。
<?php
$user = [
'id' => 1,
'email' => 'taro@example.com',
'password_hash' => password_hash('secret123', PASSWORD_DEFAULT),
];
$inputEmail = 'taro@example.com';
$inputPassword = 'secret123';
if (
$inputEmail === $user['email'] &&
password_verify($inputPassword, $user['password_hash'])
) {
echo 'ログイン成功';
} else {
echo 'メールアドレスまたはパスワードが違います。';
}実際のWebアプリでは、メールアドレスをもとにデータベースからユーザーを検索し、保存されている password_hash と入力パスワードを照合します。
エラーメッセージでは、「メールアドレスが存在しません」「パスワードだけが違います」と細かく分けすぎないことがあります。どちらが間違っているかを外部に知らせすぎると、攻撃者にヒントを与える可能性があるためです。
ログイン時は、入力されたパスワードを保存済みのハッシュ値と照合し、元のパスワードを復元しません。
セッションにログイン状態を保存する
パスワード照合に成功したら、ログイン状態をセッションに保存します。PHPでセッションを使うには、まず session_start() を呼び出します。
<?php
session_start();
// パスワード照合に成功したあと
session_regenerate_id(true);
$_SESSION['user_id'] = $user['id'];$_SESSION['user_id'] にユーザーIDを保存すると、次のページでも同じセッションからユーザーIDを取り出せます。
ここで保存しているのは、パスワードではありません。ログイン済みのユーザーを識別するためのIDです。パスワードそのものや、パスワードの入力値をセッションに保存する必要はありません。
session_regenerate_id(true) は、セッションIDを再生成するための関数です。ログイン成功時にセッションIDを作り直すことで、セッション固定攻撃のリスクを下げる目的があります。
学習用に、ログイン成功時の流れをまとめると次のようになります。
<?php
session_start();
$email = trim($_POST['email'] ?? '');
$password = $_POST['password'] ?? '';
$user = [
'id' => 1,
'email' => 'taro@example.com',
'password_hash' => password_hash('secret123', PASSWORD_DEFAULT),
];
if (
$email === $user['email'] &&
password_verify($password, $user['password_hash'])
) {
session_regenerate_id(true);
$_SESSION['user_id'] = $user['id'];
header('Location: mypage.php');
exit;
}
$error = 'メールアドレスまたはパスワードが違います。';header('Location: mypage.php') は、ログイン成功後にマイページへ移動させるためのリダイレクトです。header() を使ったあとは、意図しない処理が続かないように exit で終了します。
ログインに成功したら、パスワードではなくユーザーIDなど必要最小限の情報をセッションに保存します。
ログイン後ページとログアウト
ログイン後のページでは、セッションにユーザーIDがあるかを確認します。なければログインしていないと判断し、ログインページへ戻します。
<?php
session_start();
if (!isset($_SESSION['user_id'])) {
header('Location: login.php');
exit;
}
?>
<!doctype html>
<html lang="ja">
<body>
<p>ログイン済みのユーザーだけが見られるページです。</p>
</body>
</html>このように、ログインが必要なページの先頭でセッションを確認します。フレームワークではミドルウェアなどでまとめて処理することもありますが、基本は「セッションにログイン情報があるかを見る」ことです。
ログアウトでは、セッションに保存したログイン情報を削除します。
<?php
session_start();
$_SESSION = [];
session_destroy();
header('Location: login.php');
exit;これにより、次回以降のアクセスでは $_SESSION['user_id'] がなくなり、ログインしていない状態として扱われます。
ログイン後のページでは、セッションを確認して、ログイン済みのユーザーだけが見られるようにします。
安全なログイン処理で気をつけること
ログイン処理では、認証情報とセッションを扱うため、注意点が多くあります。
まず、パスワードを平文で保存しないことです。PHPでは、パスワード保存には password_hash()、照合には password_verify() を使うのが基本です。
次に、HTTPSを使うことです。POSTで送れば安全になるわけではありません。ログインフォームでは、通信内容を保護するためにHTTPSが重要です。
エラーメッセージにも注意します。「メールアドレスは存在しますがパスワードが違います」のように詳しく出しすぎると、登録済みメールアドレスの確認に悪用される可能性があります。一般的には「メールアドレスまたはパスワードが違います」のようにまとめることがあります。
セッションIDの扱いも大切です。ログイン成功時に session_regenerate_id(true) を呼び出すと、ログイン前のセッションIDを使い続けるリスクを下げられます。
さらに実務では、CSRF対策、ログイン試行回数の制限、多要素認証、パスワードリセット、権限管理なども関係します。この記事では基本の流れに絞りましたが、ログイン処理はWebセキュリティの入口でもあります。
ログイン処理では、認証情報とセッションを扱うため、入力チェックだけでなく通信やセッション管理にも注意が必要です。
試験ではどう問われるか
基本情報技術者試験では、ログイン処理そのもののPHPコードよりも、認証とセッション管理の考え方が重要です。
認証は、利用者が本人であることを確認する仕組みです。IDとパスワードによる認証は代表的な例です。
パスワード保存では、平文保存を避け、ハッシュ化して保存する考え方が問われることがあります。ハッシュ化は元に戻すための変換ではなく、照合に使うものです。
また、HTTPはステートレスなので、ログイン状態を維持するにはセッション管理が必要です。セッションIDが第三者に知られると、なりすましにつながる可能性があります。
試験では、ログイン処理を認証、ハッシュ化、セッション管理の組み合わせとして理解することが大切です。
実務ではどう使われるか
実務では、ログイン処理をすべて自作するより、Laravelなどのフレームワークが用意する認証機能を使うことが多いです。
それでも、基本の流れを知っていることは大切です。ログインできない、セッションが切れる、リダイレクトが繰り返される、ログアウトできない、といった不具合を調べるときに、裏側の仕組みを理解していると原因を追いやすくなります。
また、ログイン処理は権限管理にもつながります。ログインしているかどうかだけでなく、そのユーザーが管理者なのか、一般ユーザーなのか、どの画面を見られるのかを判断する必要があります。
パスワードリセット、多要素認証、アカウントロックなども、ログイン処理の周辺機能です。最初は基本の流れを押さえ、そのあとに安全性を高める仕組みを学んでいくと理解しやすくなります。
実務ではフレームワークを使うことが多くても、ログイン処理の基本を知っていると認証まわりの不具合を追いやすくなります。
まとめ: ログイン処理はフォーム、ハッシュ、セッションがつながる
ログイン処理は、フォームで送られたメールアドレスやパスワードを受け取り、本人確認を行い、成功した状態をセッションに保存する仕組みです。
パスワードは平文で保存せず、登録時に password_hash() でハッシュ化し、ログイン時に password_verify() で照合します。元のパスワードを復元するのではなく、入力値が保存済みハッシュ値に対応しているかを確認します。
ログインに成功したら、パスワードではなくユーザーIDなどをセッションに保存します。ログイン後のページではセッションを確認し、ログアウトではセッションを破棄します。
ログイン処理を理解すると、Webアプリが本人確認を行い、ログイン状態を維持する仕組みを具体的にイメージできます。

コメント