WEB APIの実装

プログラミング

レシート管理プログラムはMVCモデルを基調としていますが、一部、技術習得を目的としてWEB APIを使っています。
ブラウザ側は、非同期処理のfetch関数でサーバーにリクエストを送出します。
サーバー側は、リクエストを受け取り、処理結果をJSON形式でブラウザへレスポンスを返します。
ブラウザ側はサーバーからレスポンスが返ってくるのを待機し、レスポンスが返ってきたら処理を再開します。
この一連の実装方法を以下にまとめました。
なお、WEB API実装の説明のためにログイン認証のWEB APIを題材としていますが、ログイン認証機能については本題から外れますので、説明は省略します。

クライアント側(JavaScript)

以下のサンプルコードは、JavaScriptでWEB API(LoginCheck.php)を呼び出してログイン認証を行う非同期処理の例です。

  1. 非同期関数の定義 WEB APIを呼び出す処理は非同期で動作するため、関数定義には async キーワードを付けて、await を使った待機制御が可能なようにします。
  2. 送信データの準備 ユーザーIDやパスワードなどの送信データは、FormData オブジェクトに <キー:値> の形式で追加します。これにより、multipart/form-data 形式でサーバーに送信できます。
  3. WEB APIの呼び出し fetch メソッドを使って、LoginCheck.php に対して POST リクエストを送信します。fetch は非同期関数なので、レスポンス取得まで待機するために await を付けます。
  4. レスポンスの受信とパース サーバーからのレスポンスは JSON 形式で返されるため、response.json() を使ってパースします。この処理も非同期であるため、await を使って完了を待ちます。
  5. 認証結果に応じた処理分岐 パースされた JSON データの status プロパティを確認し、認証成功であればメニュー画面に遷移し、失敗であればアラートを表示します。
  6. エラーハンドリング 通信エラーやサーバーエラーが発生した場合は、try…catch 構文で例外を捕捉し、ログに出力します。
async function login_check(){    //非同期関数の定義 async キーワードを付けて、await を使った待機制御が可能なようにします

    /* 送信データの準備 ユーザーIDとパスワードをFormDataオブジェクトにセットします */
    const formData = new FormData();
    formData.append('uid', usernameField.value);
    formData.append('password', passwordField.value);
    formData.append('login', 'ログイン');

    try {
        /* WEB APIの呼び出し(LoginCheckプログラム(非同期処理)の完了を待ちます) */
        const response = await fetch('../LoginCheck.php', {
            method: 'POST',
            body: formData
        });

        /* レスポンスの受信とパース 受け取ったJSON形式データをパース(非同期処理)します
        const data = await response.json();

        /* 認証結果に応じた処理分岐 ログイン成功>メニュー画面表示 ログイン失敗:ログイン失敗のアラート表示 */
        if (data.status === "Authentication_OK") {
            window.location.href = '../view/TopMenuView.html';
        } else {
            alert('ログイン失敗。');
        }
    } catch (error) {
        /* エラーハンドリング */
        console.error('Fetchエラー:', error);
    }
};

サーバー側(PHP)

以下はサーバー側のプログラム例です。
処理の概要は、ユーザーIDとパスワードの認証チェックを行い、その結果を返すというものです。
認証処理の詳細についての説明は省きますが、WEB APIとするためには次の処理が重要です。

  1. リクエストを受け取る。: リクエストを受け取り、内容をチェックします。
  2. JSON形式に変換してレスポンスを返す: レスポンスヘッダーにContent-Type: application/jsonを指定し、認証結果をJSON形式にしてレスポンスを返す。

サンプルプログラム中では、次のようにコメントした部分がWEB APIにするために必要となるコードです。
/*<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
*<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<</

<?php  
/**  
 * ログインチェック ユーザーID、パスワード認証  
 */  
class LoginCheck{  
    //クラス変数を定義します  
    private $login_user = [];                              // userテーブルデータを保持する配列変数  
    private $db_connection_model;                          // DbConnectionModelのインスタンスを保持  
    private $user_table_model;                             // UserTableModelのインスタンスを保持  
    private $auth_logic_model;                             // AuthLogicModelのインスタンスを保持     
    private $uid;                                          // ログインページで入力したUIDを保持  
    private $plain_password;                               // ログインページで入力したパスワードを保持  
    private $hashed_password;                              // userテーブルの暗号化されたパスワードを保持  
    private $pass_indicate_debug;                          // 認証結果 Ok:'Authentication_OK' NG:'Authentication_NG'  

    /******************************************************
     * コンストラクタ
     *****************************************************/
    public function __construct() {
        require_once(_MODEL_REQUIRE_PATH . 'DbConnectionModel.php');
        require_once(_MODEL_REQUIRE_PATH . 'UserTableModel.php');
        require_once(_MODEL_REQUIRE_PATH . 'AuthLogicModel.php');        

        $this->user_table_model = new UserTableModel();    // UserTableModelクラスのインスタンスを生成
        $this->auth_logic_model = new AuthLogicModel();    // AuthLogicModelクラスのインスタンスを生成        
    }

    /******************************************************
     * ログインチェック
     * 認証結果 Ok:'Authentication_OK' NG:'Authentication_NG'
     *****************************************************/
    public function handleRequest() {

        $this->pass_indicate_debug='Authentication_NG';                                            // 認証結果初期値セット

        $this->auth_logic_model->session_start();                                                  // セッションを再開します

        /*<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< 
         * リクエストを受け取る
         * リクエストの内容チェック 
         *<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<</
        if (isset($_POST['login']) && $_POST['login'] === "ログイン") {

            if (isset($_POST['uid']) && isset($_POST['password'])) {

                /*
                 * ユーザーIDとパスワードチェック
                 * userテーブルとの照合
                 */
                $this->user_table_model->db_connect();                                             // データベース接続

                $this->uid = htmlspecialchars($_POST['uid'], ENT_QUOTES, 'UTF-8');

                $this->login_user = $this->user_table_model->select_UID($this->uid);               // Usreテーブル内を$uidをselect条件で検索

                /* 
                 * パスワードチェックの結果で処理分岐
                 */
                if (!empty($this->login_user)) {
                    // 認証OK
                    $this->hashed_password = trim(stripslashes($this->login_user['password']));    // テーブルの暗号化されたパスワード
                    $this->plain_password = htmlspecialchars($_POST['password'], ENT_QUOTES, 'UTF-8');  // ログインページで入力した平文パスワード

                    if($this->auth_logic_model->check_password($this->plain_password,$this->hashed_password)){
                        // パスワードチェックOKのとき
                        $this->auth_logic_model->set_login_user_to_session($this->login_user) ;    // ログインユーザー情報をセッションに保存
                        
                        $this->pass_indicate_debug='Authentication_OK';

                        /*<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
                         * レスポンスヘッダー : Content-Type: application/json
                         * JSON形式に変換してレスポンスを返す
                         *<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<</
                        header('Content-Type: application/json');                                  // Content-Type: application/jsonとする
                        echo json_encode(["status" => $this->pass_indicate_debug]);                // JSON形式でレスポンスを返す
                    } else {
                        // 認証NG
                        echo json_encode(["status" => $this->pass_indicate_debug]);                // 認証失敗を返す
                    }
                } else {
                    echo json_encode(["status" => $this->pass_indicate_debug]);                    // 認証失敗を返す
                }

            } else {
                echo json_encode(["status" => $this->pass_indicate_debug]);                        // 認証失敗を返す
            }
        }
    }
}

/********************************************************
* LoginChekクラスのインスタンスを作成し
* handleRequestメソッドを呼び出す
*********************************************************/
require_once(__DIR__ . "/BaseConfig.php");
$controller = new LoginCheck();                          // インスタンスを作成
$controller->handleRequest();                            // メソッドを呼び出す
?>

ここに掲載した内容は、Git HubのWikiにも記載し公開(パブリック)しています。

今後、公開できるドキュメントはGit Hubでも公開していこうと思っています。

コメント

タイトルとURLをコピーしました