はじめに
一般的に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 namespace App; use Tymon\JWTAuth\Contracts\JWTSubject; use Illuminate\Notifications\Notifiable; use Illuminate\Foundation\Auth\User as Authenticatable; // implements JWTSubject を追加 class User extends Authenticatable implements JWTSubject { use Notifiable; protected $fillable = [ 'name', 'email', 'password', ]; protected $hidden = [ 'password', 'remember_token', ]; // 追加 public function getJWTIdentifier() { return $this->getKey(); } // 追加 public function getJWTCustomClaims() { 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 namespace App\Http\Controllers; use Illuminate\Support\Facades\Auth; use App\Http\Controllers\Controller; class AuthController extends Controller { public function login() { $credentials = request(['email', 'password']); if (! $token = auth()->attempt($credentials)) { return response()->json(['error' => 'Unauthorized'], 401); } return $this->respondWithToken($token); } // 自身のユーザデータを取得 public function me() { return response()->json(auth()->user()); } public function logout() { auth()->logout(); return response()->json(['status' => 'ok']); } public function refresh() { return $this->respondWithToken(auth()->refresh()); } protected function respondWithToken($token) { return response()->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 use Illuminate\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を実装する方法を紹介しました。