Laravel5.5でOAuth2 Password Grant認証を試す(Laravel Passport)

3 min読了の目安(約2800字TECH技術記事

公式ドキュメントはこちらです。
Password Grant認証は、公式ドキュメントのうちの「パスワードグラントのトークン」の章に記載されてあります(短いですが...)

https://readouble.com/laravel/5.5/ja/passport.html

今回は、Laravelがインストールされている前提で、laravel passportのインストールから、パスワードグラント認証の方法まで説明します。

1. 準備する

1-1. Laravel Passportをインストール

Laravel5.5の場合は公式ドキュメントに書いてあるとおり、下記コマンドでインストールします。

composer require laravel/passport=~4.0

1-2. マイグレーションを実行する

Laravel Passportが標準で用意してくれているマイグレーションファイル達があるので、
そのままマイグレーションを実行します。

php artisan migrate

すると、以下の5個のテーブルが作られます。

  • oauth_access_tokens
  • oauth_auth_codes
  • oauth_clients
  • oauth_personal_access_clients
  • oauth_refresh_tokens

認証をする際には当然ながらusersテーブルが必要なので、
email, password カラムが存在するusersテーブルを別途用意しておく必要があります。

1-3. クライアントを生成する

下記コマンドを実行してクライアントを生成します。

php artisan passport:keys

クライアントID、クライアントシークレットが発行されますので、
.envファイルに記入していきます。

PASSPORT_CLIENT_ID=1
PASSPOER_CLIENT_SECRET=******************

2. tokenを発行するapiを作ってみる

Laravel Passportでは /oauth/token にパラメータ付きでpostリクエストを送ると、トークンが返ってくる仕組みになっているので、それを利用します。

2-1. ルーティング

好きなようにルーティング作ってください

routes/api.php

Route::post('/user/token', 'UserController@generateToken');

2-2. コントローラ内で、 /oauth/token を呼ぶ

/oauth/tokenに対して下記のパラメータを渡すと、トークンが返ってきます。

'grant_type' => 'password',
'client_id' => 'client-id', // 1-3で生成したクライアントID
'client_secret' => 'client-secret', // 1-3で生成したクライアントシークレット
'username' => 'taylor@laravel.com', // usernameと書いてるけど、ユーザーのメールアドレスを渡してください
'password' => 'my-password', // ユーザーのパスワード
'scope' => '',

直接フロント側から /oauth/token にリクエストを送ってもトークンが返ってくるのですが、処理やレスポンスをカスタマイズしたい人にとっては、自作メソッド内でトークンを生成する必要があります。

app/Http/Controllers/Api/UserController.php

<?php

namespace App\Http\Controllers\Api;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;

class UserController extends Controller
{
    public function generateToken(Request $request)
    {
        $request->merge([
            'username' => $request->email,
            'password' => $request->password,
            'grant_type'    => 'password',
            'client_id'     => env('PASSPORT_CLIENT_ID'),
            'client_secret' => env('PASSPORT_CLIENT_SECRET'),
            'scope' => '*'
        ]);

        $tokenRequest = Request::create('/oauth/token', 'post');
        $response = Route::dispatch($tokenRequest); // トークン生成
        $responseArray = json_decode($response->content(), true); // レスポンスを配列に変換

        return [
            'access_token' => $responseArray['access_token'],
            'refresh_token' =>  $responseArray['refresh_token'],
        ];
    } 
}

これで、/api/user/token に メールアドレスとパスワードをpostで送ると、アクセストークンとリフレッシュトークンが返される仕組みができました。

終わりに

Laravel Passport初めてだったので、少し苦戦しましたが、結構理解できてきました。

Laravel5.7以降はまた別のLaravel標準のAPI認証のやり方があるみたいなので、
時間がある時にそっちもチェックしてみたいと思います。