メール認証を利用した新規会員登録機能を作成します。今回はその2回目で、前回の記事に引き継ぎメール登録部分を実装していきます。
前回記事
スポンサーリンク
今回は上記のイラストにおいて、手順1・2のメール登録機能を実装していきます。
1 メール登録フォーム(registration_mail_form.php)
2 メール確認・送信(registration_mail_check.php)
まず、仮登録用のpre_memberテーブルを準備します。
pre_memberテーブル
1 2 3 4 5 6 7 |
CREATE TABLE pre_member ( id INT NOT NULL AUTO_INCREMENT PRIMARY KEY, urltoken VARCHAR(128) NOT NULL, mail VARCHAR(50) NOT NULL, date DATETIME NOT NULL, flag TINYINT(1) NOT NULL DEFAULT 0 )ENGINE=InnoDB DEFAULT CHARACTER SET=utf8; |
urltokineカラムにはURLに含めるトークンが入力されます。dateカラムにはメールアドレスが登録された日付けが入ります。flagカラムはデフォルトが0の状態で自動入力され、会員登録が完了した時に、値を1に置き換えます。
registration_mail_form.php(メール登録フォーム)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
<?php session_start(); header("Content-type: text/html; charset=utf-8"); //クロスサイトリクエストフォージェリ(CSRF)対策 $_SESSION['token'] = base64_encode(openssl_random_pseudo_bytes(32)); $token = $_SESSION['token']; //クリックジャッキング対策 header('X-FRAME-OPTIONS: SAMEORIGIN'); ?> <!DOCTYPE html> <html> <head> <title>メール登録画面</title> <meta charset="utf-8"> </head> <body> <h1>メール登録画面</h1> <form action="registration_mail_check.php" method="post"> <p>メールアドレス:<input type="text" name="mail" size="50"></p> <input type="hidden" name="token" value="<?=$token?>"> <input type="submit" value="登録する"> </form> </body> </html> |
7・8行目
クロスサイトリクエストフォージェリ(CSRF)については以下の関連ページをご参照下さい。
11行目
クリックジャッキング対策については以下の関連ページをご参照下さい。
registration_mail_check.php(メール確認・送信)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 |
<?php session_start(); header("Content-type: text/html; charset=utf-8"); //クロスサイトリクエストフォージェリ(CSRF)対策のトークン判定 if ($_POST['token'] != $_SESSION['token']){ echo "不正アクセスの可能性あり"; exit(); } //クリックジャッキング対策 header('X-FRAME-OPTIONS: SAMEORIGIN'); //データベース接続 require_once("db.php"); $dbh = db_connect(); //エラーメッセージの初期化 $errors = array(); if(empty($_POST)) { header("Location: registration_mail_form.php"); exit(); }else{ //POSTされたデータを変数に入れる $mail = isset($_POST['mail']) ? $_POST['mail'] : NULL; //メール入力判定 if ($mail == ''){ $errors['mail'] = "メールが入力されていません。"; }else{ if(!preg_match("/^([a-zA-Z0-9])+([a-zA-Z0-9\._-])*@([a-zA-Z0-9_-])+([a-zA-Z0-9\._-]+)+$/", $mail)){ $errors['mail_check'] = "メールアドレスの形式が正しくありません。"; } /* ここで本登録用のmemberテーブルにすでに登録されているmailかどうかをチェックする。 $errors['member_check'] = "このメールアドレスはすでに利用されております。"; */ } } if (count($errors) === 0){ $urltoken = hash('sha256',uniqid(rand(),1)); $url = "http://◯◯◯.co.jp/registration_form.php"."?urltoken=".$urltoken; //ここでデータベースに登録する try{ //例外処理を投げる(スロー)ようにする $dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $statement = $dbh->prepare("INSERT INTO pre_member (urltoken,mail,date) VALUES (:urltoken,:mail,now() )"); //プレースホルダへ実際の値を設定する $statement->bindValue(':urltoken', $urltoken, PDO::PARAM_STR); $statement->bindValue(':mail', $mail, PDO::PARAM_STR); $statement->execute(); //データベース接続切断 $dbh = null; }catch (PDOException $e){ print('Error:'.$e->getMessage()); die(); } //メールの宛先 $mailTo = $mail; //Return-Pathに指定するメールアドレス $returnMail = 'web@sample.com'; $name = "ウェブの葉ショップ"; $mail = 'web@sample.com'; $subject = "【ウェブの葉ショップ】会員登録用URLのお知らせ"; $body = <<< EOM 24時間以内に下記のURLからご登録下さい。 {$url} EOM; mb_language('ja'); mb_internal_encoding('UTF-8'); //Fromヘッダーを作成 $header = 'From: ' . mb_encode_mimeheader($name). ' <' . $mail. '>'; if (mb_send_mail($mailTo, $subject, $body, $header, '-f'. $returnMail)) { //セッション変数を全て解除 $_SESSION = array(); //クッキーの削除 if (isset($_COOKIE["PHPSESSID"])) { setcookie("PHPSESSID", '', time() - 1800, '/'); } //セッションを破棄する session_destroy(); $message = "メールをお送りしました。24時間以内にメールに記載されたURLからご登録下さい。"; } else { $errors['mail_error'] = "メールの送信に失敗しました。"; } } ?> <!DOCTYPE html> <html> <head> <title>メール確認画面</title> <meta charset="utf-8"> </head> <body> <h1>メール確認画面</h1> <?php if (count($errors) === 0): ?> <p><?=$message?></p> <p>↓このURLが記載されたメールが届きます。</p> <a href="<?=$url?>"><?=$url?></a> <?php elseif(count($errors) > 0): ?> <?php foreach($errors as $value){ echo "<p>".$value."</p>"; } ?> <input type="button" value="戻る" onClick="history.back()"> <?php endif; ?> </body> </html> |
16・17行目
データベースの接続を行っています。db.phpは本ページの下記に記載しています。
38・39行目
本来ならば、既に会員登録完了してあるメールアドレスかどうかを調べます。今回は実装していません。
46・47行目
URLに含めるトークンを生成し、URLにつなげています。「?urltoken=」とすることでGETメソッドによりトークンを取得できるようになります。
70〜107行目
メールアドレスをチェックしデータベースに登録されたら、ユーザにメールを通知しています。ユーザは通知されたURLのリンクから本登録画面(イラストの3部分)へと遷移してきます。
pre_memberテーブルへの仮登録
db.php(データベース接続)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
<?php function db_connect(){ $dsn = 'mysql:host=◯◯◯;dbname=◯◯◯;charset=utf8'; $user = '◯◯◯'; $password = '◯◯◯'; try{ $dbh = new PDO($dsn, $user, $password); return $dbh; }catch (PDOException $e){ print('Error:'.$e->getMessage()); die(); } } ?> |
4〜6行目
環境に合わせて適当な値を設定して下さい。
次回(3回目)はイラストの3・4の本登録の実装を説明していきます。
新規会員登録機能を作成する(3/3)[メール認証][本登録]