🌊
ID/passwordによる認証 > 一番初めの認証(使用禁止)
目次ページ https://zenn.dev/gallu/articles/05335420b8e585
前提
ID/passwordによる認証の、「一番初期に考える」実装です。
なお「洒落にならないレベルで脆弱」なので、この実装は「しないでください」。
解説
比較的簡単な「IDとパスワードによる認証」で、多分一番初めに出てきそうな実装、ですが、「平文でパスワードを保存する」とか、絶対にやっては駄目な実装なので「間違っても絶対に何が何でもやらない」ようにしましょう。
想定するテーブルレイアウト
CREATE TABLE `ログインアカウント` (
`login_id` varbinary(256) NOT NULL COMMENT 'ログインID',
`password` varbinary(256) NOT NULL COMMENT 'パスワード',
PRIMARY KEY (`login_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='1レコードが「(1ユーザの)ログイン情報」なテーブル'
実装
入力は一端、 $_POST['login_id']
と $_POST['password']
で取得可能である、とします。
また、DBハンドルは $dbh
にすでに(PDOインスタンスが)入っているもの、とします。
実装方法としては
・login_idでレコードを検索、パスワードを文字列比較
・login_idとパスワードでレコードを検索
のどちらでも動きます。
実装例(login_idとパスワードでレコードを検索、のパターン)
class Authentication
{
/**
* 認証処理本体
*
* @param string $login_id ログインID
* @param string $password ログインパスワード
* @return array|null 認証の可否(arrayなら認証成功、nullなら認証失敗)
*/
public static function login(string $login_id, string $password) : ?array
{
// ごく最低限のvalidate
if ( ('' === $id)||('' === $password) ) {
// ログイン失敗
return null;
}
// プリペアドステートメントの作成
$pre = $dbh->prepare('SELECT * FROM ログインアカウント WHERE login_id=:login_id AND password=:password;');
// 値のバインド
$pre->bindValue(':login_id', $login_id);
$pre->bindValue(':password', $password);
// SQLの実行
$r = $pre->execute();
// レコードの取得
$account = $pre->fetch( \PDO::FETCH_ASSOC );
// レコードが空なら
if (false === $account) {
// ログイン失敗
return null;
}
// ログイン成功
return $account;
}
}
// ログイン
$login_account = Authentication::login(strval($_POST['login_id'] ?? ''), strval($_POST['password'] ?? ''));
if (null === $login_account) {
// ログイン失敗
echo 'NG';
exit;
}
// XXX 以下、認可処理に続く
Discussion