PHP
laravel
Passport

[PHP] Laravel + passport 初ログイン時、プライベートアクセストークンを生成するようにする

※ 注意

OAuth の仕組みをちゃんと理解できた上の実装でないためご利用は計画的に(特に後述するユーザーテーブルにトークン保存してるところとか)

やりたかったこと

OAuth が難しくてすぐ理解できそうになかったので、認証は php artisan make:auth で自動生成されるものを再利用したかった
その上で、ログイン後 API 叩きまくり SPA したかった

また、API 認証には laravel/passport を使いたかった( laradock 然り公式が配布してるものを使うのが好きなんです ...... )

実践したこと

users テーブルにトークン保存用カラム追加

  • ログインしたユーザーはアクセストークンを発行しているか?
  • そのユーザーのアクセストークンは?

こういった問題を解決する安直な方法としてカラムを追加 !!
そのままデータベース上にあるのはどうなんだろと思い
間違いなのかもなって気はしてます
(せめて暗号化、複合化処理をかました方がいいのか ... ??)

初ログイン時の処理を加える

register した後、デフォルトでは HomeController@index に遷移するようになっていたため、これを利用

passport:install がうまくいってアクセストークン生成用キーがあれば $user->createToken('Token Name') でアクセストークンが生成できます(お手軽 !!)

<?php
...
...

    /**
     * Show the application dashboard.
     *
     * @return \Illuminate\Http\Response
     */
    public function index()
    {
        $user = Auth::user();
        $bearerToken = $user->bearer_token;
        if (is_null($bearerToken)) {
            $bearerToken = $this->firstLogin($user);
        }
        return view('home')->with([
            'token' => $bearerToken,
        ]);
    }

    /**
     * @param User $user
     * @return null|string
     * @throws \Throwable
     */
    protected function firstLogin(User $user): ?string
    {
        DB::beginTransaction();
        try {
            $token       = $user->createToken('Token Name')->accessToken;
            $bearerToken = $user->bearer_token = $token;
            $user->saveOrFail();

            $inventoryGroup                     = new InventoryGroup;
            $inventoryGroup->inventory_group_id = 1;
            $inventoryGroup->name               = '日用品';
            $inventoryGroup->user_id            = $user->user_id;
            $inventoryGroup->saveOrFail();

            Log::info('HomeController@index 初回ログイン成功', [
                'userId' => $user->user_id,
            ]);

            DB::commit();
            return $bearerToken;
        } catch (\Throwable $e) {
            Log::error('HomeController@index 初回ログイン失敗', [
                'userId' => $user->user_id,
            ]);

            DB::rollBack();
            throw $e;
        }
    }

初期データとして色々入れて見たかったのでトランザクションを貼っときました
トランザクションはる階層とかレイヤー構造意識した方がいいのかなとか色々思ったんですが今回はひとまず protected function で実装しました :pray:

おわり

無事、ログイン後 API認証 を通して API 叩くことができるようになりました :thumbsup:
なんかざっくりですがちゃんとしたやり方教えてもいいよって方は教えてください :bow: