PHPで安全なパスワード認証を作る7つのステップ

PHPで作成されたパスワード認証システムのサンプルコードとその説明 PHP
この記事は約13分で読めます。

【サイト内のコードはご自由に個人利用・商用利用いただけます】

この記事では、プログラムの基礎知識を前提に話を進めています。

説明のためのコードや、サンプルコードもありますので、もちろん初心者でも理解できるように表現してあります。

基本的な知識があればサンプルコードを活用して機能追加、目的を達成できるように作ってあります。

※この記事は、一般的にプロフェッショナルの指標とされる『実務経験10,000時間以上』を凌駕する現役のプログラマチームによって監修されています。

サイト内のコードを共有する場合は、参照元として引用して下さいますと幸いです

※Japanシーモアは、常に解説内容のわかりやすさや記事の品質に注力しております。不具合、分かりにくい説明や不適切な表現、動かないコードなど気になることがございましたら、記事の品質向上の為にお問い合わせフォームにてご共有いただけますと幸いです。
(送信された情報は、プライバシーポリシーのもと、厳正に取扱い、処分させていただきます。)

はじめに

PHPで安全なパスワード認証システムを作成したいと考えているあなたへ。

本記事では、その達成方法を詳細に7つのステップで紹介します。

各ステップごとに具体的なサンプルコードとともに詳しく説明し、実践的な理解を深めていきます。

この記事を読めば、PHPを用いて確実なパスワード認証システムを実装することができます。

それでは、いきましょう。

●PHPとパスワード認証の基本

まずは、PHPとパスワード認証について簡単に説明しておきます。

これらの基本的な知識を理解しておくことで、後のステップがより理解しやすくなります。

○PHPとは?

PHPは、ウェブ開発に広く使われているサーバーサイドのスクリプト言語です。

HTMLと組み合わせることで、動的なウェブページを作成することができます。

また、データベースとの連携も容易で、ユーザーの情報を管理したり、ウェブサイトの動作を制御したりするのに便利です。

○パスワード認証とは?

パスワード認証は、ユーザーが自分自身を証明する一般的な方法です。

ユーザー名とパスワードを入力し、その組み合わせが登録情報と一致することを確認することで、システムはユーザーの身元を確認します。

このプロセスは、ユーザーのプライバシーとセキュリティを保護するために重要な役割を果たします。

●PHPでパスワード認証を作るステップ

それでは具体的な作業に移りましょう。

ここからは、PHPでパスワード認証システムを作成するための7つのステップを紹介します。

○ステップ1:データベース接続

パスワード認証システムを作成するためには、まずユーザーの情報を保存する場所が必要です。

そのためのデータベースとPHPを接続することがステップ1です。

□サンプルコード1:データベース接続

PHPからMySQLデータベースへ接続するためのサンプルコードを紹介します。

<?php
$dbhost = 'localhost';
$dbuser = 'username';
$dbpass = 'password';
$dbname = 'database';
$conn = new mysqli($dbhost, $dbuser, $dbpass, $dbname);

if ($conn->connect_error) {
  die('データベース接続失敗: ' . $conn->connect_error);
}
echo 'データベース接続成功';
?>

このコードでは、mysqliオブジェクトを使ってMySQLデータベースへ接続を試みています。

この例では、まずデータベースのホスト名、ユーザー名、パスワード、データベース名を変数に代入しています。

そして、新しいmysqliオブジェクトを作成し、データベースへの接続を試みています。

接続に失敗した場合はエラーメッセージを表示し、プログラムを終了します。

成功した場合は、成功メッセージを表示します。

○ステップ2:ユーザー登録

ユーザーが新しくシステムを利用するためには、まずユーザー情報をデータベースに登録する必要があります。

このステップでは、そのユーザー登録の処理について説明します。

□サンプルコード2:ユーザー登録

ユーザーのユーザー名とパスワードをデータベースに登録するためのサンプルコードを紹介します。

<?php
$username = $_POST['username'];
$password = $_POST['password'];

$sql = "INSERT INTO users (username, password) VALUES (?, ?)";
$stmt = $conn->prepare($sql);
$stmt->bind_param("ss", $username, $password);

if($stmt->execute()){
  echo 'ユーザー登録が完了しました';
}else{
  echo 'エラーが発生しました: ' . $stmt->error;
}
?>

このコードでは、まずPOSTからユーザー名とパスワードを取得しています。

次に、SQLのINSERT文を用いて新しいユーザーをデータベースに登録します。

SQL文はプリペアドステートメントとして実行されます。

これにより、SQLインジェクション攻撃から保護することができます。

登録が成功した場合は、成功メッセージを表示します。エラーが発生した場合は、エラーメッセージを表示します。

○ステップ3:パスワードのハッシュ化

パスワードを平文で保存することはセキュリティ上好ましくありません。

もしデータベースが漏洩した場合、ユーザーのパスワードがそのまま露呈してしまうからです。

そこで、パスワードをハッシュ化(一方向の暗号化)し、そのハッシュ値をデータベースに保存します。

□サンプルコード3:パスワードのハッシュ化

PHPのpassword_hash関数を使ってパスワードをハッシュ化するサンプルコードを紹介します。

<?php
$password = $_POST['password'];
$hashed_password = password_hash($password, PASSWORD_DEFAULT);

$sql = "INSERT INTO users (username, password) VALUES (?, ?)";
$stmt = $conn->prepare($sql);
$stmt->bind_param("ss", $username, $hashed_password);

if($stmt->execute()){
  echo 'ユーザー登録が完了しました';
}else{
  echo 'エラーが発生しました: ' . $stmt->error;
}
?>

このコードでは、POSTから取得したパスワードをpassword_hash関数でハッシュ化し、その結果をデータベースに保存しています。

password_hash関数は、パスワードを安全にハッシュ化するための関数です。

第二引数にはハッシュ化アルゴリズムを指定します。

PASSWORD_DEFAULTは現時点でPHPが推奨するデフォルトのアルゴリズムを指定する定数です。

ハッシュ化したパスワードをデータベースに保存することで、元のパスワードを知られても安全性が維持されます。

○ステップ4:ログイン機能

ユーザー登録とパスワードのハッシュ化が終わったら、次はログイン機能を作成します。

ユーザーが自分のユーザー名とパスワードを入力し、それがデータベース内の情報と一致するかどうかを確認するプロセスを作成します。

□サンプルコード4:ログイン機能

ユーザー名とパスワードを使ってログインを試みるサンプルコードを紹介します。

<?php
$username = $_POST['username'];
$password = $_POST['password'];

$sql = "SELECT * FROM users WHERE username = ?";
$stmt = $conn->prepare($sql);
$stmt->bind_param("s", $username);

$stmt->execute();
$result = $stmt->get_result();
$user = $result->fetch_assoc();

if ($user && password_verify($password, $user['password'])) {
    session_start();
    $_SESSION['username'] = $username;
    echo 'ログインに成功しました';
} else {
    echo 'ユーザー名またはパスワードが間違っています';
}
?>

このコードでは、まずPOSTからユーザー名とパスワードを取得しています。

次に、入力されたユーザー名がデータベースに存在するかを確認します。

存在する場合、password_verify関数を用いて入力されたパスワードとデータベースに保存されているハッシュ化されたパスワードが一致するかを確認します。

一致する場合は、セッションを開始し、ユーザー名をセッションに保存します。

これにより、その後のページでユーザーがログイン状態であることを確認できます。

○ステップ5:セッション管理

ログインが成功したら、そのユーザーがログイン状態であることをシステムが覚えておく必要があります。

これを実現するためには、セッション管理が必要です。

セッションは、ユーザーがブラウザを閉じるか、明示的にログアウトするまで維持されます。

□サンプルコード5:セッション管理

セッション管理を行うためのサンプルコードを紹介します。

<?php
session_start();

if (isset($_SESSION['username'])) {
    echo 'ようこそ、' . $_SESSION['username'] . 'さん';
} else {
    echo 'ログインしてください';
}
?>

このコードでは、まずsession_start関数を用いてセッションを開始します。

その後、$_SESSIONスーパーグローバル変数を用いてセッション情報を取得します。

ユーザー名がセッションに保存されている場合、そのユーザー名を表示します。

保存されていない場合、つまりユーザーがログインしていない場合は、ログインを促します。

セッション管理により、ユーザーがログインしている状態を保持できます。

○ステップ6:ログアウト機能

ログアウト機能は、ユーザーが自分のセッションを終了し、自分のアカウントからログアウトできるようにする機能です。

ユーザーがログアウトすると、そのセッションは無効になり、その後のページアクセスでは新たにログインが必要になります。

□サンプルコード6:ログアウト機能

ログアウト機能を実装するためのものサンプルコードを紹介します。

<?php
session_start();

if (isset($_SESSION['username'])) {
    unset($_SESSION['username']);
    echo 'ログアウトしました';
} else {
    echo 'すでにログアウトしています';
}
?>

このコードでは、まずsession_start関数を用いてセッションを開始します。

次に、$_SESSIONスーパーグローバル変数を用いてユーザー名がセッションに保存されているかどうかを確認します。

ユーザー名がセッションに保存されている場合、すなわちユーザーがログインしている場合は、そのユーザー名をセッションから削除し、ログアウトしたことを表示します。

ユーザー名がセッションに保存されていない場合、つまりユーザーが既にログアウトしている場合は、その旨を表示します。

○ステップ7:エラーハンドリング

エラーハンドリングは、プログラムが予期せぬエラーに遭遇した場合に適切に対応するための重要なステップです。

エラーハンドリングを適切に行うことで、ユーザーに対して明確なエラーメッセージを表示することができ、ユーザーが何が問題であるのかを理解する助けになります。

□サンプルコード7:エラーハンドリング

エラーハンドリングを実装するためのサンプルコードを紹介します。

<?php
$username = $_POST['username'];
$password = $_POST['password'];

if (empty($username) || empty($password)) {
    echo 'ユーザー名とパスワードは必須です';
    exit;
}

$sql = "SELECT * FROM users WHERE username = ?";
$stmt = $conn->prepare($sql);
$stmt->bind_param("s", $username);

$stmt->execute();
$result = $stmt->get_result();
$user = $result->fetch_assoc();

if ($user && password_verify($password, $user['password'])) {
    session_start();
    $_SESSION['username'] = $username;
    echo 'ログインに成功しました';
} else {
    echo 'ユーザー名またはパスワードが間違っています';
}
?>
¥

このコードでは、まずユーザー名とパスワードがPOSTリクエストから取得されます。

その後、これらの入力が空でないかを確認します。

どちらかが空の場合は、エラーメッセージを表示し、プログラムを終了します。

入力が正しい場合は、データベースからユーザー情報を取得し、パスワードが正しいかを確認します。

パスワードが正しい場合は、ユーザー名をセッションに保存し、ログイン成功メッセージを表示します。

パスワードが間違っている場合は、エラーメッセージを表示します。

以上が、PHPで安全なパスワード認証を作る7つのステップの最後のステップです。

次に、PHPでのパスワード認証の注意点と対処法について説明します。

●PHPでのパスワード認証の注意点と対処法

パスワード認証システムの開発には、セキュリティが極めて重要です。

開発者としてはユーザーのデータを守り、信頼を維持することが求められます。

PHPでパスワード認証を行う際の注意点と対処法を挙げます。

1.パスワードの平文保存

ユーザーのパスワードをデータベースに平文で保存しないことが絶対的なルールです。

万が一データベースが攻撃された場合、ユーザーのパスワードが第三者に漏れる危険性があります。

パスワードをハッシュ化することで、原形を復元することが非常に難しくなります。

2.SQLインジェクション

ユーザーからの入力をそのままSQLクエリに組み込むと、攻撃者が任意のSQL文を実行することが可能になります。

これを防ぐためには、プリペアドステートメントを用いると良いです。

3.セッションハイジャック

攻撃者がユーザーのセッションIDを盗み取り、そのユーザーとして行動することです。

これを防ぐためには、HTTPSを使用する、セッションIDを定期的に変更するなどの対策があります。

以上のような注意点を押さえつつ、安全なパスワード認証システムを作成しましょう。

●パスワード認証のカスタマイズ例

基本的なパスワード認証システムを作成した後は、ユーザーの体験を向上させるためのカスタマイズを行うことができます。

例えば、次のようなカスタマイズが考えられます。

  1. パスワード再設定機能:ユーザーがパスワードを忘れた場合に、安全に新しいパスワードを設定できる機能です。
  2. 二段階認証:パスワードだけでなく、メールやSMSでの認証コードを必要とすることで、セキュリティを一層強化できます。
  3. パスワードポリシー:パスワードの強度を高めるために、一定の長さや特定の文字を含むことを強制するルールを設けます。

これらの機能を追加することで、ユーザー体験とセキュリティを同時に向上させることが可能となります。

まとめ

この記事では、PHPで安全なパスワード認証システムを作成する7つのステップを紹介しました。

初めてパスワード認証システムを作成する方でも、これらのステップに従って進めていけば、基本的なシステムを構築できるはずです。

最後に、セキュリティに配慮しつつ、ユーザー体験を向上させるためのカスタマイズについても触れました。

これらを踏まえて、ぜひ安全で使いやすいパスワード認証システムの開発に挑戦してみてください。