人気のPHP WEBアプリケーションフレームワークLaravelのTips。 (Laravelアプリの初期化)composer create-project laravel/laravel my-app

LaravelでFirebaseのjwt(accessToken)を認証する

PHP用のいろいろなパッケージがありますが、firebase / php-jwt を使用してみます

● firebase / php-jwt

https://github.com/firebase/php-jwt

インストール

composer require firebase/php-jwt
composer require guzzlehttp/guzzle

 

vi tests/Unit/VerifyFirebaseTokenTest.php

tests/Unit/VerifyFirebaseTokenTest.php

<?php

namespace Tests\Unit;

use Tests\TestCase;
use Firebase\JWT\JWT as FirebaseJWT;
use Firebase\JWT\Key;
use Illuminate\Support\Facades\Http;

class VerifyFirebaseTokenTest extends TestCase
{
    /**
     * @testdox JWTトークンが正しい場合 verifyJWT() メソッドは true を返す
     */
    public function test_verify_firebase_auth_jwt()
    {
        $verify_result = $this->verifyJWT("<検証したいjwtをここに貼り付ける>");
        $this->assertTrue($verify_result);
    }

    /**
     * Firebase Auth の jwtを検証する(公開鍵はgoogleサーバから取得する)
     * @param   string    $accessToken 
     * @returns boolean
     */
    public function verifyJWT($accessToken)
    {
        $kid = $this->getKidFromJwtHeader($accessToken);
        $publicKey = $this->getPublicKeyFromFirebase('https://www.googleapis.com/robot/v1/metadata/x509/securetoken@system.gserviceaccount.com', $kid);
        $key = new Key($publicKey, 'RS256');

        $decoded = null;
        try {
            $decoded = FirebaseJWT::decode($accessToken, $key);
            return ($decoded) ? true : false;
        } catch (\Throwable $th) {
            // throw new Error('error 発生');
            return false;
        }
    }


    /**
     * jwtからヘッダの中のkidを取得
     * @param   string    $token 
     * @returns string
     */
    public function getKidFromJwtHeader($token)
    {
        $jwtHeader = $this->getJwtHeader($token);
        $obj = json_decode($jwtHeader, true);
        return $obj['kid'];
    }

    /**
     * jwtからヘッダを取得
     * @param   string $token 
     * @returns string
     */
    public function getJwtHeader($token)
    {
        $tokenHeader = preg_split('/\./', $token)[0];
        $jwtHeader = base64_decode($tokenHeader);
        return $jwtHeader;
    }

    /**
     * Firebaseのjwt検証用公開鍵を取得する
     * @param   string      $url 
     * @param   string      $kid 
     * @returns string
     */
    public function getPublicKeyFromFirebase($url, $kid)
    {
        $response = Http::get($url);
        $body = $response->body();
        $publicKeys = json_decode($body, true);
        $key = $publicKeys[$kid];
        return $key;
    }
}

● テストの実行

php artisan test --testdox  tests/Unit/VerifyFirebaseTokenTest.php

● 認証後に Laravelユーザーと紐付ける

公式の Userモデルを参考に Userモデルにカラム「uid_google」を追加する

php artisan make:migration change_userss_table_add_uid_google  --table=users

マイグレーションファイルを以下の内容で保存します

<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
    /**
     * Run the migrations.
     */
    public function up(): void
    {
        Schema::table('users', function (Blueprint $table) {
            $table->string('uid_google',128)->nullable()->after('id')->comment('UID(Firebase)');
        });
    }

    /**
     * Reverse the migrations.
     */
    public function down(): void
    {
        Schema::table('users', function (Blueprint $table) {
            $table->dropColumn('uid_google');
        });
    }
};
php artisan migrate
No.2223
09/24 14:37

edit