🐡

openapi-generatorで生成したLaravel 7のプロジェクトでLaravel Passportを使用する

2021/10/09に公開

openapi-generatorで生成できるコードがLaravel 7のコードなのでちょっとハマる。

この記事では、Github OpenAPITools/openapi-generatorで生成したスケルトンプロジェクトにコマンド等を実行して、Laravel Passportを使用した認証を使用できるようにするまでのステップを書いています。

Laravel 7 + Laravel Passport
公式doc

参考にさせていただいた記事

https://www.whizz-tech.co.jp/1442/
https://www.whizz-tech.co.jp/1453/

プロジェクトを作成

openapi.yamlのあるディレクトリで以下のコマンドを実行

$ docker run --rm -v `pwd`:/work openapitools/openapi-generator-cli:latest generate -i /work/openapi.yaml -g php-laravel -o /work
$ sudo chown -R `whoami`:`whoami` ./lib

composer.jsonのプロジェクト名は xxx/yyy の形式に書き換える。

passportをインストール

$ cd ./lib
$ composer require laravel/passport:^9

最新だと依存が解決できずエラーになるので明示的にv9を指定する。

migrate

ローカルはsqliteでやる

.env.exampleをコピーして.env.localを作成する

~省略~

LOG_CHANNEL=stack

DB_CONNECTION=sqlite

CACHE_DRIVER=file
QUEUE_CONNECTION=sync

env作成後はリンクを張っておくと便利

$ ln -s .env.local .env

アプリケーションキーを生成

$ php artisan key:generate

DB用のファイルを追加

$ touch ./database/database.sqlite

migrate

$ php artisan migrate

passportの初期化

$ php artisan passport:install --uuids

yesをタイプして進むとDBのマイグレーションが再度実行される。

passportの設定

User.phpは生成した場合は存在しないので自分で作成する。

AuthServiceProviderのbootでPassport用のroutesを追加する。

# いろいろ省略
use Laravel\Passport\Passport;

class AuthServiceProvider extends ServiceProvider
{
    # 省略
    
    public function boot() {
        $this->registerPolicies();
	Passport::routes();
    }
}

guardsでpassportの認証を使用するように修正。

  'guads' => [
      'api' => [
          'driver' => 'passport',
	  'provider' => 'users',
      ]
  ]

Userのモデルを作成

openapi-generatorで生成したコードには自分で定義しない限りはUserモデルがないので自分で配置する。

自分で定義している場合は、生成されたModelを修正する。

<?php

namespace App\Models;

use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Laravel\Passport\HasApiTokens;

class User extends Authenticatable
{
    use HasApiTokens, Notifiable;
    
    protected $fillable = [
        "name",
	"email",
	"password",
    ];
}

auth driverが参照するモデルを変更する

省略
    'providers' => [
        'users' => [
            'driver' => 'eloquent',
            'model' => App\Models\User::class, 
        ]
    ]
 
省略

routingができてるか確認する

起動

$ php artisan serve
$ curl -s http://localhost:8000/oauth/tokens -H "Accept: application/json" | jq
{
  "message": "Unauthenticated."
}
$ curl http://localhost:8000/api/user -H "Accept: application/json" | jq
{
  "message": "Unauthenticated."
}

初期ユーザを登録

アプリケーションの仕様に合わせてユーザ登録用のAPIやコマンドを実装して、初期ユーザを登録する。

クライアントを作成

パスワードで認証可能なユーザを作成する。

$ php artisan passport:client --password

クライアント名などの入力を進めて、client idとsecretが出力されたら控えておく。

トークンを発行する

登録したユーザ情報と、発行したclient id, secretを使用してトークンをリクエストする。

$ curl -X POST http://localhost:8000/oauth/token \
  -H "Accept: application/json" \
  -d "grant_type=password" \
  -d "client_id=<client id>" \
  -d "client_secret=<client secret>" \
  -d "username=<登録したユーザのID>" \
  -d "password=<登録したユーザのパスワード>" \
  -d "scope="

レスポンスでaccess_tokenとrefresh_tokenが返ってくればOK

Discussion