狐の避暑地

PHPやJavaでプログラミングをしてます。狐が好きです。備忘録やゲームについて置いてあります。

簡単なセキュリティ対策をしながらIDとPasswordを登録する方法

使う目的

  • ユーザの登録を必要とした環境で、何も考えずにサクッと書きたい
  • セキュリティは必要最低限の対策をしたいけど、面倒な実装はしたくない
  • どんなユーザ管理をするにしても基本の書き方なので備忘録兼

環境

php5 + apache2

MySQL5.6

方針

  1. IDは英数字のみ有効、PasswordはHash化する
  2. IDとHashedPasswordをデータベースに書き込む
  3. それを用いてユーザ認証を行う
免責

セキュリティ上問題がある記述をしている場合もあります。そのまま使用して問題が起こった場合でも責任は負えません。

IDとPasswordを処理する

POSTメソッドでid, pswdを受け取って

<?php
mb_language("ja");
mb_internal_encoding("UTF-8");
header('X-FRAME-OPTIONS:DENY');

$r = rand(1000,9999);

if(!isset($_POST['id'], $_POST['pswd']){
    //Parameter Manipulation対応
    die("");
}
//英数字以外の撃ち落とし(簡易版)
//XSS, SQL Injection対応
$userid = mb_ereg_replace("/[^0-9a-zA-Z]/", "", $_POST['id']);

//不正な文字があった場合別の処理を行う
if($userid === $_POST['id']){
    die("");
}

$hashedPswd = sha1($r.$userid.$_POST['pswd']."^v^Teeeeemo^v^");

?>
DBに書き込み

実際に使用する場合は先頭のdefineを書き換えて下さい

<?php
//ひとつ前の$r, $hashedPswd, $useridを使用します

//この辺を書き換えて使ってね
define('SQL_HOST', "localhost"); //SQLホスト名
define('SQL_USER', "root"); //SQLユーザ名
define('SQL_PSWD', "pswd"); //SQLパスワード

define('DB', "dbName"); //データベース名
define('TABLE', "tableName"); //テーブル名

//登録するときに発行するQuery
$regQuery  = "INSERT INTO ". DB . "." . TABLE;
$regQuery .= "(`r`, `userid`, `hashedPswd`) ";
$regQuery .= "VALUES ('". $r . "', '" . $userid . "', '" . $hashedPswd . "')";

//すでに登録されているかどうかを確認するQuery
$chkQuery  = "SELECT * FROM `". TABLE . "` WHERE `userid` = '" . $userid . "'" ;

//SQL接続開始
$sqlLink = mysqli_connect(SQL_HOST, SQL_USER, SQL_PSWD);
if(!$sqlLink){die("");}
mysqli_set_charset($sqlLink, "utf8");
if(mysqli_select_db($sqlLink, DB)){die("");}

//SELECT→fetchしてみてNULLでないなら存在するuserid
$sql_result = mysqli_query($sqlLink, $chkQuery);
if(mysqli_fetch_row($sql_result) != NULL){
    die("登録済みのID");
}

//登録を行う
mysqli_query($sqlLink, $regQuery);
?>

認証を実際に行う

POSTでidとpswdを受け取ってから動作。$rはデータベースから読み出し。

<?php

//ログインに成功したユーザ名は$logonUserに返却される。NULLならログイン失敗。
$logonUser = NULL;

define('SQL_HOST', "localhost"); //SQLホスト名
define('SQL_USER', "root"); //SQLユーザ名
define('SQL_PSWD', "pswd"); //SQLパスワード

define('DB', "dbName"); //データベース名
define('TABLE', "tableName"); //テーブル名

//入力されたuserid, pswdを登録時とおなじ手順を踏んでcheck

//英数字以外の撃ち落とし(簡易版)
//SQL Injection対応
$userid = mb_ereg_replace("/[^0-9a-zA-Z]/", "", $_POST['id']);

//useridをSELECTし正解のデータを受け取るQuery
$sltQuery  = "SELECT * FROM `". TABLE . "` WHERE `userid` = '" . $userid . "'" ;

//SQL接続開始
$sqlLink = mysqli_connect(SQL_HOST, SQL_USER, SQL_PSWD);
if(!$sqlLink){die("");}
mysqli_set_charset($sqlLink, "utf8");
if(mysqli_select_db($sqlLink, DB)){die("");}

$sqlResult = mysqli_query($sqlLink, $sltQuery);
$userData = mysqli_fetch_array($sqlResult);
mysqli_free_result($sqlResult);
mysqli_close($sqlLink);

//登録時と同じ方法でパスワードを認証
$challengePswd = sha1($userData['r'].$userid.$_POST['pswd']."^v^Teeeeemo^v^");

if($challengePswd === $userData['pswd'] && $userid === $userData['userid']){
    $logonUser = $userData['userid'];
}else{
    $logonUser = NULL;
}

?>
備考