IoT+WEBのためのホームサーバ計画の実装編12。普通のWeb部分。ログイン関連4。loginちょっと仕上。
ログインをそれらしく
では、ログインをそれらしくしましょう。
まず、画面から。
ボタンは3つ、通常のログイン、新規登録、パスワードのリセットです。
では、通常のログインから行きましょう。
通常のログイン
ユーザが登録されているかどうか確認するには、ユーザ名(mail)とパスワードの組み合わせが一致してるかどうか見るので、それをSQLで書いちゃいましょう。
$sql = "select count(*) as hira from T_user where username='{$userid}' and passmd5='{$userpass}' and regist=1;";
$sql = "select count(*) as hira from T_user where username='{$userid}' and regist=1;";
$sql = "select count(*) as hira from T_user where username='{$userid}';";
●ユーザとパスワードが一致し、registフラグがたってるもの。
● ユーザが一致し、registフラグがたってるもの。
● ユーザのみ一致したもの。
ここらへんの件数をひっかけて、判断させますね。
全て一致してればOK。
ユーザ名が一致しててregistフラグがたってるけどパスワードがあって無ければ、単にパスワードが違ってるってこと。
ユーザ名しかあってなければ、まぁ登録した形跡はあるということ。
それをまとめて書くと、
require_once "hiraDB.php";
require_once "hiraDef.php";
session_start();
$userid = $_POST["userid"];
$userpass = $_POST["userpass"];
$retV = array();
$db = new hiraDB();
$retv = $db->open();
$sql = "select count(*) as hira from T_user where username='{$userid}' and passmd5='{$userpass}' and regist=1;";
$sql2 = $sql;
$AR = $db->query($sql);
$n = $AR[0]["hira"];
$sql = "select count(*) as hira from T_user where username='{$userid}' and regist=1;";
$AR = $db->query($sql);
$m = $AR[0]["hira"];
$sql = "select count(*) as hira from T_user where username='{$userid}';";
$AR = $db->query($sql);
$l = $AR[0]["hira"];
$db->close();
if($n == 0){
$status = "NG";
if($m != 0){
$code = PASSWORD_FALT;
}else{
if($l == 0){
$code = USER_NOT_FOUND;
}else{
$code = NOT_AUTH;
}
}
}else{
$status = "OK";
$code = 0;
}
$retV["code"] = $code;
$retV["status"] = $status;
$retV["message"] = getMes($code);
header( "Content-Type:text/html; charset=utf-8");
echo json_encode($retV);
これはまぁここだけで完結してるので、特にどうってことないですね。
次に、新規登録です。
ユーザ新規登録
フロー的には、まぁメールでの認証いれたりするので、こんな感じです。
ユーザ名とパスワードをDB登録し、registフラグを0にします。
そして、拡張のカラムを使って、GUIDっぽいものを2つ登録しときます。
このGUIDをGUID,GUID2とすると、
登録URL?g=GUID&g2=GUID2
みたいな感じでアクセスしてもらって、登録完了にします。
もちろん、時間も30分とかに限定です。
書くと、こんな感じで。
<?php
require_once "hiraDef.php";
require_once "hiraDB.php";
require_once "hiraMailer.php";
session_start();
$userid = $_POST["userid"];
$userpass = $_POST["userpass"];
$retV = array();
$db = new hiraDB();
$retv = $db->open();
$nowdate = time().PHP_EOL;
$lastdate = $nowdate;
$guid = md5("{$nowdate}");
$guid2 = md5($guid);
$code = 0;
$sql = "select count(*) as hira from T_user where username='{$userid}';";
$AR = $db->query($sql);
$n = (int)$AR[0]["hira"];
if($n == 1){
$code = USER_ALREDAY_REGIST;
$retV["status"] = "NG";
$retV["code"] = $code;
$retV["message"] = getMes($code);
$retV["alt"] = $sql;
header( "Content-Type:text/html; charset=utf-8");
echo json_encode($retV);
exit;
}
$sql = "insert into T_user (username,passmd5,regist,registdate,lastdate,note,etc) VALUES ('{$userid}','{$userpass}',0,{$nowdate},{$lastdate},'{$guid}','{$guid2}');";
$results = $db->execute($sql);
$db->close();
if(!$results){
$code = USER_ADD_SQL_FALT;
}
$_SESSION["finred"]["userid"] = $userid;
$RU = $_SERVER["REQUEST_URI"]; // [REQUEST_URI] => /000.php
preg_match("/.*\\//", $RU ,$am);
$url = $_SERVER['REQUEST_SCHEME'] . "://" . $_SERVER['SERVER_NAME'] . "{$am[0]}/newregist.php?g={$guid}&g2={$guid2}";
$userid = $_POST["userid"];
$to = $userid;
$subject = "FINRED IoT Web registration!";
$body = "以下のリンクで、30分以内に登録してください。\nクリックするだけでOKです。\n{$url}";
$a = new hiraMailer;
$a->exec($subject,$body,$to);
$retV["status"] = "OK";
$retV["results"] = $results;
$retV["message"] = getMes($code);
$retV["alt"] = $alt;
$retV["alt2"] = $alt2;
header( "Content-Type:text/html; charset=utf-8");
echo json_encode($retV);
?>
まぁGUIDって言っても、ここではUNIXTIMEをMD5してるだけですけどね。
この段階で、DBにはユーザ、パス(のMD5)、registフラグ無し、登録UNIXTIME、最終更新UNIXTIME、拡張用文字のGUIDをいれてる感じです。
このままでログインしようとしても、
まだ認証されてません
というメッセージが出ることになります。
そうそう、何気にPHPMailerなるものを使ってます。
ささやかなラッパーのみ作ってつかってます。
その部分がこれ。
require_once "./PHPMailer/PHPMailerAutoload.php";
class hiraMailer{
private $CharSet;
private $Host;
private $Username;
private $Password;
private $SMTPSecure;
private $Port;
private $From;
private $fromname;
//-------------------------
/* 初期値 */
//-------------------------
function __construct(){
$this->CharSet = "UTF-8";
$this->Host = "smtp.gmail.com";
$this->Username = "********";
$this->Password = "********";
$this->SMTPSecure = 'CRAM-MD5';
$this->Port = 587;
$this->From = "********@********.com";
$this->fromname = "FINRED_IoT_web";
}
//-------------------------
function exec($subject,$body,$to){
$mail = new PHPMailer(true);
$mail->CharSet = $this->CharSet;
$mail->isSMTP();
$mail->SMTPDebug = 0;
$mail->Host = $this->Host;
$mail->SMTPAuth = true;
$mail->Username = $this->Username;
$mail->Password = $this->Password;
$mail->SMTPSecure = $this->SMTPSecure;
$mail->Port = $this->Port;
$mail->From = $this->From;
$mail->IsHTML(false);
$mail->FromName = mb_encode_mimeheader($this->fromname, "JIS", "UTF-8");
$mail->Subject = mb_encode_mimeheader($subject, "JIS", "UTF-8");
$mail->Body = $body;
$mail->AddAddress($to);
if ($mail->Send()) {
return true;
} else {
return false;
}
}
//-------------------------
};
パスワードのリセット
パスワードのリセットは、まぁやってることは、GUIDをふたつ突っ込んで、メールを飛ばして、
そこに30分以内にちゃんと来たら、パスワードをリセットして、新たに、登録してもらうだけです。
なので、やってることは大したことないですね。
もちろん、
そのパスワードは以前と同じなので登録できません^^;
とかやるのであれば、まぁまたちょっとDB管理すればいいだけなのですが、
今回はそこまでやってませんです。