LaravelPassportを使用して、Nuxt.jsからのログインと、ログイン後の認証を行う方法


Laravel側設定

composerコマンド実行

Laravel Passprotのインストール

make:authコマンド実行

ログイン、ユーザ登録、パスワードリセットのベースを構築

migration実行

make:authコマンドで以下テーブルのマイグレーションファイルが追加されているはずなのでマイグレーション実行

以下のテーブルが追加されます。

・oauth_access_tokens
・oauth_auth_codes
・oauth_clients
・oauth_personal_access_clients
・oauth_refresh_tokens

これは、vendor/laravel/passport/database/migrations配下のマイグレーションファイルをしている模様

passport:installコマンド実行

以下コマンドで、認証に必要なシークレットキーを生成します。

oauth_clientsテーブルに2レコード追加されますが、これは、アクセストークンを生成するために使用する、「パーソナルアクセス」クライアントと「パスワードグラント」クライアントとなります。

UserモデルへLaravel\Passport\HasApiTokensトレイトを追加

このトレイトを追加することで、認証済みユーザのトークンとスコープを確認するためのヘルパメソッドがUserモデルへ提供されます。

routes/api.phpに、Passportによるルーティングを適用します。

このルートにはアクセストークンの発行、アクセストークンの失効、クライアントとパーソナルアクセストークンの管理のルートが含まれます。

公式には、AuthServiceProviderのbootメソッドから、Passport::routesメソッドを呼び出すとありますが、自分の場合、CORSを設定するミドルウェアを作成して、api/~のPrefixURLでアクセスした場合、必ずそこを通るようにしていたため、routes/api.phpにてルーティングを設定しました。

これにより、以下のルーティングが追加されていることが確認できます。

※AuthServiceProviderで、引数無しで、Passport::routesメソッドを呼び出した場合は、apiのPrefixが付きません。もし、mAuthServiceProviderで、任意のルートに変更する場合は以下の記事が参考になります。(CORS対応する場合、ミドルウェアを別途追加しなければいけないので、routeに直接記載したほうがスッキリする気がしますが・・。)

laravel/passportのrouteのprefixをデフォルトのoauth/から任意のルートに変更する【Laravel5.5】 – Qiita

 

config/auth.phpのguardsのapiのdriverをpassportへ変更

これにより、認証のAPIリクエストが送信された時は、パスポートのTokenGuardを使用するようになります。

configのキャッシュを削除しておく

Nuxt.js側設定

Laravel PassportではOAuth2.0に沿った4つの認可方法があります。

今回は、ユーザのパスワード情報を利用してトークンの取得する「Password Grant」を使用し、アクセストークンを取得します。

Laravel Passportでは、/oauth/tokenにpostすることでアクセストークンを取得することができます

まず、ログインフォームを作成します。

■pages/login/index.vue

php artisan make:authで、作成した場合、usersテーブルのemail = usernameとなります。こちらは適宜変更可能ですが、今回はこのままでいきます。

画面は以下のようなかんじですね。

また、コンポーネント内でAPIアクセスすると、記述が膨大になり、見通しも悪くなるので、そちらは、LoginRepository.jsに処理をまとめてみました。(★マークの部分)

この設計は、下記の記事を参考にしています。(ファクトリパターンは特に必要なかったので、適用していません。)

Vue.jsでのAPIリクエストをaxios&RepositoryFactoryパターンで実装する

【Vue.js】Web API通信のデザインパターン (個人的ベストプラクティス) – Qiita

 

■repositories/LoginRepository.js

 

※Password Grantを使用する場合、oauth/tokenへpostするデータは以下の通りになります。

・grant_typeは、’password’固定

・client_idは、oauth_clientsテーブルのid(今回は’2’)

・client_secretは、oauth_clientsテーブルのsecret

※client_idと、client_secretは、 passport:install コマンド実行時、oauth_clientsテーブルに、oauth_clients.name=”Laravel Password Grant Client”で、生成されたレコードを参照してください。

・usernameは、usersテーブルのemail(デフォルトの場合)

・password:は、usersテーブルのpassword

 

■repositories/Repository.js

 

usersテーブルに登録してあるユーザー情報でログインし、成功すると、以下のように、response.data.access_tokenにて、トークンを取得することができます。

■pages/login/index.vue

このトークンをクッキーや、Vuexや、sessionStrageなどに保存しておきます。(上記例ではクッキー)

認証が必要なAPIを投げる時は、取得したアクセストークンをリクエストのAuthorizationヘッダへBearerトークンとして入れます。

そうすることで、laravelのrouteにて、 ->middleware('auth:api') と指定したパスにアクセスすることが出来ます。

■routes/api.php(例)

■repositories/UserRepository.js

■repositories/Repository.js

認証が失敗した場合は、「Status Code: 401 Unauthorized」が返ってくるので、★の箇所で、ログインページに戻したり、リフレッシュトークンなどを保持しておいて、アクセストークンを更新する処理をかいたり、よしなに処理を記載します。

以上で、完了ですが、アクセストークンの取り回しや、認証処理の共通化については、今後も検討し、良い方法があれば、ブログに追記していきたいと思います。

 

———————

この記事がお役に立てたら、是非シェアをお願いします^^