php
web
会員制のウェブサイトを作るための会員登録のページを作りました。
登録のページではまず
-
ユーザ名・パスワードを入力してもらう。
受けとったユーザ名・パスワードを保存する。
ポイントはハッシュを使って、パスワードがわからないようにすることです。
これをしないと、万一パスワードを保存したファイルが見られたしまったときに、本当のパスワードがばれてしまいます。
外から見えない文字列(ソルト)とユーザーが入力したパスワードを連結してから
パスワードをハッシュ関数で変換します(l.13)。
$password = hash("sha256", [ユーザーが入力したパスワード] . [ソルト]);
"sha256"はハッシュに使うアルゴリズムの名前です。
ここではソルトは定数にしていますが、本当に安全にしたいときはユーザーごとに違う値(例えばユーザー名のハッシュ)
にすれば、さらに安全です。
保存したユーザー名・パスワードのファイルを見られないようにすることも重要です。
ここではmkdirのオプションで
mkdir($user_path . $username, 0700)
のように所有者以外アクセス禁止 (700) のパーミッションを設定しています(l.16)。
コードは以下です。
<?php //ハッシュ化に使用する定数 $salt_password = "salting_sample";//本当はもっと難しいものにする $salt_username = "salting_sample2";//本当はもっと難しいものにする $user_path = "./users/"; $status = "none"; $error_message = "不明なエラーです。時間をおいて再度ご登録ください。"; if(!empty($_POST["username"]) && !empty($_POST["password"])){ //パスワードはハッシュ化する $username = hash("sha256", $_POST["username"] . $salt_username); $password = hash("sha256", $_POST["password"] . $salt_password); if(!file_exists($user_path . $username)) if(!mkdir($user_path . $username, 0700)) { $status = "failed"; $error_message = "登録情報の保存に失敗しました。時間をおいて再度ご登録ください。"; } else { file_put_contents($user_path . $username . "/password.txt", $password); file_put_contents($user_path . $username . "/username.txt", $_POST["username"]); $status = "ok"; } else //ユーザ名が使われていたらNG $status = "failed"; $error_message = "ユーザー名が既に使われています。"; } ?> <!DOCTYPE html> <html> <head> <meta charset="UTF-8" /> <title>新規登録</title> </head> <body> <h1>新規登録</h1> <?php if($status == "ok"): ?> <?--登録成功--> <p>登録完了</p> <?php elseif($status == "failed"): ?> <?--失敗--> <p> エラー: <?php echo "${error_message}\n"; ?> </p> <?php else: ?> //入力フォーム <form method="POST" action="register.php"> ユーザ名:<input type="text" name="username" /> パスワード:<input type="password" name="password" /> <input type="submit" value="登録" /> </form> <?php endif; ?> </body> </html>実行例はこちらです。
動作としては
-
「登録」ボタンを押すと登録完了
同じ名前で再度登録しようとするとエラー
次回:PHPでログインページ②