Laravel

【2020年4月 時点】LaravelでJWT認証! jwt-auth 導入手順

みなさん、こんにちは。どんぶラッコです。

LaravelをAPIサーバとして使う人も多いと思います。

その時に一番苦労するのが認証周りですよね。

ということで、本日は、jwt-authを使って、JWT認証をLaravelで導入する手順についてまとめていきます!

インストール

まずは、composer を使って jwt-auth をインストールします。

composer require tymon/jwt-auth

次に、vendor:publishコマンドを入力します

php artisan vendor:publish --provider="Tymon\JWTAuth\Providers\LaravelServiceProvider"

ちなみにLaravelServiceProvider の中身はこんな感じです。 jwtの機能をLaravelで使えるようにしてくれてると考えておけばとりあえずOKです。

namespace Tymon\JWTAuth\Providers;

use Tymon\JWTAuth\Http\Parser\AuthHeaders;
use Tymon\JWTAuth\Http\Parser\InputSource;
use Tymon\JWTAuth\Http\Parser\LumenRouteParams;
use Tymon\JWTAuth\Http\Parser\QueryString;

class LumenServiceProvider extends AbstractServiceProvider
{
    /**
     * {@inheritdoc}
     */
    public function boot()
    {
        $this->app->configure('jwt');

        $path = realpath(__DIR__.'/../../config/config.php');
        $this->mergeConfigFrom($path, 'jwt');

        $this->app->routeMiddleware($this->middlewareAliases);

        $this->extendAuthGuard();

        $this->app['tymon.jwt.parser']->setChain([
            new AuthHeaders,
            new QueryString,
            new InputSource,
            new LumenRouteParams,
        ]);
    }
}

そして、シークレットキーを生成。

php artisan jwt:secret

これで初期のセットアップは完了です。

ファイルを作成する

では、ここから実際にjwtを使えるように変更を加えていきましょう。

app/UserModelを更新します。

<?php

namespace App;

use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Tymon\JWTAuth\Contracts\JWTSubject;

class User extends Authenticatable implements JWTSubject
{
    use Notifiable;

		/* 省略 */

    /**
     * JWT の subject claim となる識別子を取得する
     *
     * @return mixed
     */
    public function getJWTIdentifier()
    {
        return $this->getKey();
    }

    /**
     * キーバリュー値を返します, JWTに追加される custom claims を含む
     *
     * @return array
     */
    public function getJWTCustomClaims()
    {
        return [];
    }
}

そして、 config/auth.php を設定。

<?php
    
    return [
    		
    		// guard と passwords をそれぞれ何を使うかを設定。
        // apiサーバとしてjwttokenを使いたいので web を api に変更
    
        'defaults' => [
            // 'guard' => 'web',
    				'guard' => 'api', 
            'passwords' => 'users',
        ],
    
        // 
    
        'guards' => [
            'web' => [
                'driver' => 'session',
                'provider' => 'users',
            ],
    
            'api' => [
                // 'driver' => 'token',
    						'driver' => 'jwt',
                'provider' => 'users',
                'hash' => false,
            ],
        ],
    ];

さて、ここまでできたら jwtドライバを使って認証ができるようになります!

ということであとは route/api.php と コントローラを作成・変更していきましょう。

まずは route/api.phpから

Route::group([
    'prefix' => 'auth'
], function () {
    Route::post('login', 'AuthController@login');
});

Route::group([
    'prefix' => 'auth',
    'middleware' => 'auth:api'
], function () {
    Route::post('logout', 'AuthController@logout');
    Route::post('refresh', 'AuthController@refresh');
    Route::post('me', 'AuthController@me');
});

続いて、AuthControllerを作成。

php artisan make:controller AuthController

中身をこのように書き換えます。

<?php

namespace App\Http\Controllers;

use Illuminate\Support\Facades\Auth;
use App\Http\Controllers\Controller;

class AuthController extends Controller
{
    /**
     * Create a new AuthController instance.
     *
     * @return void
     */
    public function __construct()
    {
        $this->middleware('auth:api', ['except' => ['login']]);
    }

    /**
     * Get a JWT via given credentials.
     *
     * @return \Illuminate\Http\JsonResponse
     */
    public function login()
    {
        $credentials = request(['email', 'password']);

        if (! $token = auth()->attempt($credentials)) {
            return response()->json(['error' => 'Unauthorized'], 401);
        }

        return $this->respondWithToken($token);
    }

    /**
     * Get the authenticated User.
     *
     * @return \Illuminate\Http\JsonResponse
     */
    public function me()
    {
        return response()->json(auth()->user());
    }

    /**
     * Log the user out (Invalidate the token).
     *
     * @return \Illuminate\Http\JsonResponse
     */
    public function logout()
    {
        auth()->logout();

        return response()->json(['message' => 'Successfully logged out']);
    }

    /**
     * Refresh a token.
     *
     * @return \Illuminate\Http\JsonResponse
     */
    public function refresh()
    {
        return $this->respondWithToken(auth()->refresh());
    }

    /**
     * Get the token array structure.
     *
     * @param  string $token
     *
     * @return \Illuminate\Http\JsonResponse
     */
    protected function respondWithToken($token)
    {
        return response()->json([
            'access_token' => $token,
            'token_type' => 'bearer',
            'expires_in' => auth()->factory()->getTTL() * 60
        ]);
    }
}

これで完了です!

テスト用のユーザを作る

最後に、テストユーザを作って、実際に処理が通るかを確認しましょう。

そのためにSeederでユーザをチャチャっと作成します。

php artisan make:seeder UsersTableSeeder

database/seeds/UserTableSeederを編集

<?php

use Illuminate\Database\Seeder;

class UsersTableSeeder extends Seeder
{
    /**
     * Run the database seeds.
     *
     * @return void
     */
    public function run()
    {
        DB::table('users')->insert([
            'name' => 'test',
            'email' => 'test@test.com',
            'password' => bcrypt('testtest'),
        ]);
    }
}

その後、DatabaseSeeder に UsersTableSeederを追加。

<?php

use Illuminate\Database\Seeder;

class DatabaseSeeder extends Seeder
{
    /**
     * Seed the application's database.
     *
     * @return void
     */
    public function run()
    {
         $this->call(UsersTableSeeder::class);
    }
}

あとは、

php artisan db:seed

コマンドを入力すればOKですね!

Login処理を送ってみよう!

では、先ほど作成したテストユーザでloginをしてみましょう。今回はPostmanというサービスを使ってPOST通信を送っています。

access_token が返ってきていたらOKです!!


以上で基本の設定は完了です!ぜひチャレンジしてみてください♪

ABOUT ME
どんぶラッコ
ECコンサルタント、システムエンジニアを経て、quintet株式会社CTOに就任。普段はNuxt.jsやLaravelを使用しています。

\面白いと思ったら/

記事のシェア & Twitter のフォロー をお願いします!

@proglearn
RELATED POST

COMMENT

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です