インターンでLaravelでJWT(Json Web Token)を用いた認証システムの実装をしてみたので、まとめてみる。
参考にしたサイト
以下のサイトをとても参考にしました。
https://dev-yakuza.github.io/laravel/jwt/
https://jwt-auth.readthedocs.io/en/develop/
上記二つのサイトを参考に機能を実装しました。今回の記事は公式リファレンスを参考にして書いていきます。
JWTをインストールする
1.以下のコマンドを実行じてjwt-authをインストールする。
$ composer require tymon/jwt-auth
2.config/app.phpのproviderの箇所に以下のコードを追加。
'providers' => [
...
Tymon\JWTAuth\Providers\LaravelServiceProvider::class,
]
3.configファイルを生成するために以下のコマンドを実行
$ php artisan vendor:publish --provider="Tymon\JWTAuth\Providers\LaravelServiceProvider"
4.シークレットキーを発行するために以下のコマンドを実行。
$ php artisan jwt:secret
諸々の準備
1.User.phpに以下のように変更。Tymon\JWTAuth\Contracts\JWTSubjectをUserモデル上で使えるようにするための処理。
<?php
namespace App;
use Tymon\JWTAuth\Contracts\JWTSubject;
use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;
class User extends Authenticatable implements JWTSubject
{
use Notifiable;
// Rest omitted for brevity
/**
* Get the identifier that will be stored in the subject claim of the JWT.
*
* @return mixed
*/
public function getJWTIdentifier()
{
return $this->getKey();
}
/**
* Return a key value array, containing any custom claims to be added to the JWT.
*
* @return array
*/
public function getJWTCustomClaims()
{
return [];
}
}
2.config/auth.phpを以下のように変更。jwtのguardを使えるようにするための処理。
'defaults' => [
'guard' => 'api',
'passwords' => 'users',
],
...
'guards' => [
'api' => [
'driver' => 'jwt',
'provider' => 'users',
],
],
3.routingの追加。
Route::group([
'middleware' => 'api',
'prefix' => 'auth'
], function ($router) {
Route::post('register', 'AuthController@register');
Route::post('login', 'AuthController@login');
Route::post('logout', 'AuthController@logout');
});
4.コントローラーの新規作成。これで準備完了です!
$ php artisan make:controller AuthController
JWTでサインアップ機能とサインイン機能を実装する
完成コードは以下です。主要コードだけ切り取ったのでバリデーションとかは一切つけていません。
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Auth;
use App\User;
use JWTAuth;
class JWTAuthController extends Controller
{
public function __construct()
{
$this->middleware('api', ['except' => ['login']]);
}
public function register(Request $request){
$user = new User;
$user->fill($request->all());
$user->password=bcrypt($request->password);
$user->save();
return $this->publishToken($request);
}
public function login(Request $request){
return $this->publishToken($request);
}
protected function publishToken($request) {
$token = auth('api')->attempt(['email' => $request->email, 'password' => $request->password]);
return $this->respondWithToken($token);
}
protected function respondWithToken($token) {
return response()->json([
'access_token' => $token,
'token_type' => 'bearer',
'expires_in' => auth('api')->factory()->getTTL() * 60,
'user' => auth('api')->user(),
]);
}
}
以下の部分でユーザーの新規作成(サインアップ)とサインインを行う。最後にpublishTokenメソッドを呼び出す処理を書く。
public function register(Request $request){
$user = new User;
$user->fill($request->all());
$user->password=bcrypt($request->password);
$user->save();
return $this->publishToken($request);
}
public function login(Request $request){
return $this->publishToken($request);
}
publishTokenメソッドでTokenの発行を行い、そのTokenを持たせた状態でrespondWithTokenメソッドを呼び出す。
protected function publishToken($request) {
$token = auth('api')->attempt(['email' => $request->email, 'password' => $request->password]);
return $this->respondWithToken($token);
}
そしてrespondWithTokenメソッドでjsonとサインアップもしくはサインインしたユーザーの情報を返すようにする。
protected function respondWithToken($token) {
return response()->json([
'access_token' => $token,
'token_type' => 'bearer',
'expires_in' => auth('api')->factory()->getTTL() * 60,
'user' => auth('api')->user(),
]);
}
access_tokenにTokenが入った状態でレスポンスが帰って来れば成功です!