PHP ログインフォームを作成する (HTML,リダイレクト処理、エラーチェック、ファイル保存)
今回は以前作成したPHPによる自作メールフォームを応用する形で
ログインするためのフォームを作成したいと思います
まずは簡単に流れを確認したいと思います
GETでの要求
ユーザーがIDとパスワードを入力して送信する
POSTでの要求が来た場合
入力された値をチェックする
値が正しければメンバー専用ページへリダイレクトする処理をする
この流れで制作してきます
まず今回は簡単にBootstrapも使用し
HTMLを制作しておきます
はい
こんな感じで一旦はHTMLだけ生成しました
入力用のinputタグのvalueは今は空にしておきます
次に作成するのは必要事項を入力してもらって、送信ボタンが押され専用ページにジャンプする仕組みを作ります。
まず、フォームタグのaction属性で自身のページに来るように設定しているためページの最上部にPHPでの条件を書いておきます
前回のお問合せフォームでの復習ですが
submitボタンを押された時の送信方式はPOSTで送信されるため
それを判定して分岐させ、
全ての条件で問題なければリダイレクトするように処理を書きます
<?php
if (isset($_POST)) {
$host = $_SERVER['HTTP_HOST'];
$url = rtrim(dirname($_SERVER['PHP_SELF']),'/\\');
header("Location: //$host$url/memberonly.php");
exit();
} else {
//こっちはGETでアクセスされた時の処理
}
?>
新しい関数が出てきましたので解説します
$host = $_SERVER[‘HTTP_HOST’];
$_SERVERはスーパーグローバル変数なのでこちらに現在のサイトのいろいろな情報が詰まっています
その中で今回は‘HTTP_HOST’というドメイン名を取得できる変数を使用しています
リクエストのHost:ヘッダの内容(ドメイン名)となるため、
「example.com」となります
$_SERVER[‘PHP_SELF’]
こちらはドメインから繋がるディレクトリです
現在実行しているスクリプトのファイル名が取得できるつまり、
ドキュメントルートから取得されます。login.phpとなる部分ですね
dirname()ディアネーム関数はその中からディレクトリだけを抽出する関数で、
渡したパスの親ディレクトリのパスが文字列で返却されます。今回の自分のディレクトリだとLoginForm/までが抽出されます
さらにrtrim()アールトリム関数で右側の「/」を取り除く処理を行います。
別にheader関数にFULLのURLを打ち込んでおいても問題はありません。
しかしこうしてサーバー側から取れる変数にしておくことで仮にドメインや引っ越しなどで移転したとしても常に同じ動作をしてくれる事が可能になります。
これでリダイレクトの処理でページ遷移ができるようになったのでindex.phpをコピーしてmemberonly.phpを簡単に用意しておきます
もちろんPHPの処理やログイン用のinputタグは必要ないのでこのあたりは削除してそれぞれのコンテンツを用意しておきます。
ユーザーの登録用画面を作成する
ここではregister.php という新規ファイルを作成しユーザー情報を登録する画面を作成します
登録してもらう内容は
- Eメール
- パスワード
- パスワード(確認用)
- 登録ボタン
こんなところですね
register.phpへの概要を考えます
このファイルへのアクセスはlogin.php と似ていてGETで来た場合は入力画面を表示するようにし、POSTで来た場合はログイン画面を表示するという動きですね
そしてPOSTで来た場合は上記の入力項目をチェックする必要があります
まず確認しなければいけないことは、
入力必須
200文字以内
Eメール形式かどうか
入力必須
100文字以内
入力必須
100文字以内
上記のパスワードと一致するかどうか
こちらのバリデーションを行う必要があります
バリデーションやサニタイズなどのセキュリティ備忘録は前回行ったのでこちらは割愛し簡単にコードを書いていきます
HTMLもログイン画面用のやつをコピーして
パスワードだけさらに確認用に複製し、name属性はp2とします。
$err_msg = [];
if ($_POST) {
if (!$_POST['e']) {
$err_msg[] = "メールアドレスを入力してください。";
} else if ( mb_strlen($_POST['e']) > 200 ) {
$err_msg[] = "メールアドレスは200文字以内でご記入ください。";
} else if (!filter_var($_POST['e'], FILTER_VALIDATE_EMAIL)) {
$err_msg[] = "メールアドレスは正しくご記入ください。";
}
if (!$_POST['p']) {
$err_msg[] = "パスワードを入力してください。";
} else if ( mb_strlen($_POST['p']) > 100 ) {
$err_msg[] = "パスワードは100文字以内でご記入ください。";
}
if (!$_POST['p2']) {
$err_msg[] = "確認用パスワードを入力してください。";
} else if ( mb_strlen($_POST['p2']) > 100 ) {
$err_msg[] = "確認用パスワードは100文字以内でご記入ください。";
}
if ($_POST['p'] !== $_POST['p2']) {
$err_msg[] = "確認用パスワードが一致しません。";
}
if (!$err_msg) {
$host = $_SERVER['HTTP_HOST'];
$url = rtrim(dirname($_SERVER['PHP_SELF']),'/\\');
header("Location: //$host$url/index.php");
exit();
}
} else {
}
次に
ユーザー情報を隠しファイルに保存する
ということで
認証用データとして保管しておくファイルを作ります
概要としては
- userinfo.txtとして作る
- Eメール、暗号化したパスワード :形式で保存する
- 項目はコンマで区切る
- ファイル形式はCSV形式にする
- 項目ごとにダブルクォーテーションで囲う
- パスワードの暗号化は必須
- 行末は改行する
上記のルールで保存します
パスワードは必ず暗号化(ハッシュ化)する必要があります
ハッシュ化と暗号化は微妙に意味が違っていて、ハッシュ化されたパスワードは元の文字列には戻すことが出来ません
したがってユーザーが入力したパスワードは都度ハッシュ化されて、ハッシュ化された文字列同士が一致するかどうかで判断します
またこの個人情報のuserinfo.txtファイルはFTPのpublic_htmlの中に置いてはいけません。 ここは誰でもアクセスできるような場所であるため、情報漏えいに繋がりかねないためです。
password_hash()関数を使おう
ということでこの関数でパスワードのハッシュ化を行います
password_hash(パスワード文字列 , PASSWORD_DEFAULT←これがマスト引数);と引数もほぼ固定であり、認証させるのも専用関数があるため使いやすいです。
似たような関数でmb5やsha1という関数もありますがこちらは常に同じハッシュ値を生成してしまうため現代では破るのは容易なようで、もしもサイト改修などで見かけたら必ず訂正するようにします。
file_put_contents()ファイルに書き込む関数
次にファイルに書き込むための関数も紹介します
この関数は引数を3つ指定します
file_put_contents(ファイル名,書き込む文字列,追加書き込みモード);
と指定します、追加書き込みモードに関しては
FILE_APPENDを指定して末尾に追加するようにします
if (!$err_msg) {
$userfile = '../../userinfo.txt';
$ph = password_hash($_POST['p'] , PASSWORD_DEFAULT);
$line = '"'.$_POST['e'].'","'.$ph.'"'."\n";
$ret = file_put_contents($userfile,$line,FILE_APPEND);
}
はい
こうですね。
まず入力チェックでエラーがなければというif文から始まり、生成ファイルの変数化、パスワードのハッシュ化を行いそれを文字列としてコンマでつないで変数にします
最後の$ret変数は確認用ですのでまた後で使用します
これで問題なくファイル作成と書き込みが行われるはずです
しかしまだこれでは同じメールアドレスを何件も登録できてしまうため、同じアドレスの場合はエラーになるようにしないといけません
流石に長くなってきたので記事を分けようと思います
タイトルにTODOを書いておいて見やすくしておきます
今回はここまでです。
では次回も頑張って覚えましょう
コメントをお待ちしております