はじめに
一般的にWebには認証機能があるケースが多いと思います。今回はLaravelで認証APIを作る方法として、JWTを使った方法を紹介します。
条件
以下のバージョンを対象としています。
- PHP 7.3
- Laravel 5.5
JWTとは
JWTとは、JSON Web Token の略で認証情報のやり取りに用いられます。JWTの仕組みについてはこちらを御覧ください。
準備
認証機能を有効化
以下のコマンドでLaravelの認証機能を有効化させます。
1 2 | $php artisan make:auth $php artisan migrate |
マイグレーションは実行しておきましょう。
1 | $php artisan migrate |
jwt-authのインストール
JWTのライブラリとして jwt-auth を使用します。以下の通りインストールします。
1 | $composer require tymon/jwt-auth |
コンフィグファイルの作成
以下のコマンドを実行してコンフィグファイルを作成します。実行すると config/jwt.php が生成されます。
1 | php artisan vendor:publish--provider="Tymon\JWTAuth\Providers\LaravelServiceProvider" |
secretの作成
以下のコマンドを実行して secret を作成します。実行すると、.env に JWT_SECRET が設定されます。
1 | php artisan jwt:secret |
Userモデルを修正
今回は既存のユーザーモデルを認証に使います。ユーザーモデルに2つのメソッドを追加します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | <?php namespaceApp; useTymon\JWTAuth\Contracts\JWTSubject; useIlluminate\Notifications\Notifiable; useIlluminate\Foundation\Auth\User asAuthenticatable; // implements JWTSubject を追加 classUserextendsAuthenticatableimplementsJWTSubject { useNotifiable; protected$fillable=[ 'name','email','password', ]; protected$hidden=[ 'password','remember_token', ]; // 追加 publicfunctiongetJWTIdentifier() { return$this->getKey(); } // 追加 publicfunctiongetJWTCustomClaims() { return[]; } } |
guardを修正
config/auth.php を修正します。
1 2 3 4 5 6 7 8 9 10 11 12 13 | 'defaults'=>[ 'guard'=>'api',// 変更 'passwords'=>'users', ], // 省略 'guards'=>[ 'api'=>[ 'driver'=>'jwt',// 変更 'provider'=>'users', ], ], |
認証用コントローラーの作成
コントローラーを作成して認証機能を実装します。以下のコマンドで AuthController.php を作成します。
1 | php artisan make:controller AuthController |
作成したコントローラーに認証機能を実装します。ログイン中のユーザーのデータは auth()->user() で取得できます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | <?php namespaceApp\Http\Controllers; useIlluminate\Support\Facades\Auth; useApp\Http\Controllers\Controller; classAuthControllerextendsController { publicfunctionlogin() { $credentials=request(['email','password']); if(!$token=auth()->attempt($credentials)){ returnresponse()->json(['error'=>'Unauthorized'],401); } return$this->respondWithToken($token); } // 自身のユーザデータを取得 publicfunctionme() { returnresponse()->json(auth()->user()); } publicfunctionlogout() { auth()->logout(); returnresponse()->json(['status'=>'ok']); } publicfunctionrefresh() { return$this->respondWithToken(auth()->refresh()); } protectedfunctionrespondWithToken($token) { returnresponse()->json([ 'access_token'=>$token, 'token_type'=>'bearer', 'expires_in'=>auth()->factory()->getTTL()*60 ]); } } |
ルーティング設定
routes/api.php に作成したメソッドを紐づけます。
1 2 3 4 5 6 7 8 9 10 11 12 13 | <?php useIlluminate\Http\Request; Route::group(['middleware'=>'guest:api'],function(){ Route::post('/login','AuthController@login'); }); Route::group(['middleware'=>'auth:api'],function(){ Route::get('/me','AuthController@me'); Route::post('/logout','AuthController@logout'); Route::post('/refresh','AuthController@refresh'); }); |
疎通確認
curlで疎通確認をしてみましょう。ユーザーデータは予め作成しておいてください。
以下のようにリクエストを投げると、
1 | $curl http://localhost/api/login -d email=hoge@example.com -d password=123456 |
以下のようなレスポンスが返却されます。
1 2 3 4 5 | { "access_token":"eyJhbGciOiJiUzL1NiIsInR5cCI6IkpcVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwsiwib3FtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab10RMHtHDcEfsjoYZgeFONFh7HgQ", "token_type":"bearer", "expires_in":3600 } |
また、認証が必要なAPIをコールする場合は、以下のように Authorization ヘッダーに Bearer: {token} を付加してリクエストを投げます。
1 | $curl-H"Authorization: Bearer eyJhbGciOiJ...."http://localhost/api/me |
さいごに
jwt-auth を使ってLaravelでログインAPIを実装する方法を紹介しました。