ketyiaの作ってみた

このサイトでは作ってみたことを記事にまとめていきます!

PHPで認証機能を作成してみる!①

こんにちは!IT学習中のKeitaと申します。

今回はPHP認証機能(ログイン、ログアウト)を作成していこうと思います!

正直、認証機能はフレームワーク(LaravelやCakePHP等)を使用すると簡単に作れます。しかし、認証処理の流れ原理を知っていないと、フレームワークを使用していたとしても修正機能追加等対応できなくなると思います。

なので、今回はPHPで一から作成していこうと思います!

本記事では、ユーザ登録についてまとめていきます!

テーブル作成


データベース名は
loginとしておきます!
テーブルは下記としておきます!
※認証機能を確認するための最底辺の情報のみにフォーカスを当てます!

①ユーザのログイン情報をまとめたテーブル
テーブル名:【login_users】
・ログインユーザ情報ID  (識別子)
・ログインid  (メールアドレス)
・パスワード  (パスワード)

②ユーザのログイン状況を確認するテーブル
テーブル名:【login_session】
・ログインセッションID (識別子)
・ログインユーザ情報ID (ログインユーザの識別子) ※FK
・キー (ログインした証明)

これをXampp環境でA5m2というツールを使い作成していきます!
下記のようになりました。


簡単ですが、こんなところでしょうか。。
リレーションを活用しています!

ユーザ登録機能


機能の流れとしては、入力データから情報をデータベースに登録するという処理です。

流れをしては、下記の順になります。

・HTMLでひな型作成+データの受け渡し
・データベースに連携し、入力値を登録
・すでに登録されているユーザの再登録を防ぐ

HTMLでひながら作成+データの受け渡し


HTMLは下記のような画面を用意しました!
これを使用していきます。


これをPHPで読み込んで、値を受け渡す処理を書いていきます!

ーーーーーーーーーーーーーーーーー
【user_regist.php

<?php
session_start();

// 変数の宣言
$error_message = '';
$mail = '';

// エラーが発生している時の処理
if(!empty($_SESSION['error_message'])){
    $error_message = $_SESSION['error_message'];
    unset($_SESSION['error_message']);
}

// それぞれの変数に値を代入
if ( !empty( $_SESSION['mail'] ) ){
    $mail = $_SESSION['mail'];
    unset( $_SESSION['mail'] );
}

// パスワードは保持しない
if ( !empty( $_SESSION['password'] ) ){
    unset( $_SESSION['password'] );
}

// テンプレートとなるhtmlファイルを読み込む
$html = file_get_contents( 'user_regist.html' );

// htmlファイルの変更したい部分を変換する
$html = str_replace( '#error_message#', htmlspecialchars( $error_message ), $html );
$html = str_replace( '#mail#', htmlspecialchars( $mail ), $html );

// 変換したhtmlを表示する
print( $html );

ーーーーーーーーーーーーーーーーー

これで、PHPでHTMLを表示させることやセッションでデータを受け渡せているはずです。※動作確認はまとめて行います!

データベースに連携し、入力値を登録


それでは、データをデータベースに登録する処理を書いていきます!
コードは下記になりました!先ほどのユーザ登録画面の登録画面を押されたときに呼び出させるPHP処理です。

ーーーーーーーーーーーーーーーーー
【user_regist_complete.php

<?php
session_start();

// 変数の宣言
$error_message = '';
$mail = '';
$password = '';
$password_confirm = '';

// 受け取る
$mail = $_GET['mail'];
$password = $_GET['password'];
$password_confirm = $_GET['password_confirm'];

// エラーチェック
// ①値が空の場合
if ( empty( $mail ) || empty( $password ) || empty( $password_confirm ) ) {
    $error_message .= '①項目が入力されていません';
}
// ②パスワードが一致していない場合
if ( strcmp( $password, $password_confirm ) !== 0 ) {
    $error_message .= '②パスワードが一致しません';
}
// エラーの①と②どちらか一つでもエラーがある場合は登録画面に戻す
if ( !empty( $error_message ) ){
    $_SESSION['error_message'] = $error_message;
    $_SESSION['mail'] = $mail;
    header( 'Location: user_regist.php' );
    exit;
}
// パスワードをハッシュ化
$password_hash = password_hash( $password, PASSWORD_DEFAULT );
// データベース処理
$db = new PDO('mysql:host=localhost;dbname=login','root','');

try{
    $db->beginTransaction();


    // ログイン情報の登録
    // SQL文実行
    $sql = 'INSERT INTO login_users ( login_id , password )
       VALUES( :login_id, :password);';
    // 事前にSQL登録
    $sth = $db->prepare($sql);

    // 変数名にパラメーターをバインド
    $sth->bindParam(':login_id', $mail);
    $sth->bindParam(':password', $password_hash);

    // 実行
    $sth->execute();

    // コミット
    $db->commit();

} catch ( Exception $e ) {
    // ロールバックする
    $db->rollback();
    echo "データベースエラー" . $e->getMessage();
}

unset($_SESSION['mail']);

// テンプレートとなるhtmlファイルを読み込む
$html = file_get_contents( 'user_regist_complete.html' );

// 変換したhtmlを表示する
print( $html );

ーーーーーーーーーーーーーーーーー

と、これでデータベースに登録ができるはずです。
一旦動作確認をしてみます!


idが17であるのは何度か試行錯誤したということで。。
ともかく登録できてますね!成功です。

すでに登録されているユーザの再登録を防ぐ


今の状態だと同じloginID(メールアドレス)でも登録できてしまうことになってしまいます!

これは防いでおきたいですよね。。
これの対処法を考えていきます!

データベースの登録箇所を少し変更します!try文の中身を変えます
ーーーーーーーーーーーーーーーーー
【user_regist_complete.php

try{
    $db->beginTransaction();
   
    // ユーザの複数登録チェック
    $sql = 'SELECT login_id FROM login_users
            WHERE login_id = :login_id;';
   
    // 事前にSQL登録
    $sth = $db->prepare($sql);
   
    // 変数名にパラメーターをバインド
    $sth->bindParam(':login_id', $mail);
   
    // 実行
    $sth->execute();
   
    // 結果を取得する
    $result = $sth->fetch();
   
    if(!empty($result)){
        $error_message = '③すでに登録されています';
        $_SESSION['mail'] = $mail;
        $_SESSION['error_message'] = $error_message;
        header( 'Location: user_regist.php' );
        exit;
    }else{
        // ログイン情報の登録
        // SQL文実行
        $sql = 'INSERT INTO login_users ( login_id , password )
                VALUES( :login_id, :password);';
        // 事前にSQL登録
        $sth = $db->prepare($sql);

        // 変数名にパラメーターをバインド
        $sth->bindParam(':login_id', $mail);
        $sth->bindParam(':password', $password_hash);
       
        // 実行
        $sth->execute();
   
        // コミット
        $db->commit();
    }

ーーーーーーーーーーーーーーーーー

はい。これでどうでしょうか!
動作確認してみます!


はい。同ユーザIDの登録を防ぐことができました!
これでユーザ登録完成です。

次の記事では、ログインの機能についてまとめていきます!

begginerkun.hatenablog.com