LoginSignup
34
34

More than 5 years have passed since last update.

LaravelでJWT(jwt-auth利用)

Last updated at Posted at 2018-10-07

passportは標準なので安心感がある一方、ちょっと大げさなのでとりあえずtymon/jwt-authも試してみる。

内容はこちらの記事を参考にさせていただきました(ほぼ同じ。すみません)。

本家サイトにある暫定マニュアルも参考になります。

準備

インストール

参考記事ではrc2でしたが、既にrc3に。あと書き方変わったみたいです。本家サイトでバージョンを確認しましょう。

composer require tymon/jwt-auth v1.0.0-rc.3

Provider等への登録

Laravel 5.5からPackage Auto Discovery対応なのでいらないみたい。

composer.jsonのdont-discoverで無効にもできる。

初期化?コマンドの実行

インストールしたら初期化コマンドを実行します。config/jwt.phpが生成されます。

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

secretの生成

続いて鍵のsecretを発生させます。

php artisan jwt:secret

Userモデルの修正

今回は、(token発行時のID,PW)認証にUserモデルを利用するので、必要な変更を加えます。

モデルを変更する場合は自フェーズのauth.phpのproviderをいじるといいと思います。
implements JWTSubjectを行います。

app/User.php
<?php

namespace App;

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

use Tymon\JWTAuth\Contracts\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の修正

続いてGuardの設定を変更します。

config/auth.php
<?php

return [

    'defaults' => [
        'guard' => 'web',
        'passwords' => 'users',
    ],


    'guards' => [
        'web' => [
            'driver' => 'session',
            'provider' => 'users',
        ],

        'api' => [
+           'driver' => 'jwt',
            'provider' => 'users',
        ],
    ],


    'providers' => [
        'users' => [
            'driver' => 'eloquent',
            'model' => App\User::class,
        ],

    ],


    'passwords' => [
        'users' => [
            'provider' => 'users',
            'table' => 'password_resets',
            'expire' => 60,
        ],
    ],

];

Controllerの作成と記述

ApiControllerを作成します。

php artisan make:controller ApiController

必要な記述を行います。

ApiController.php
<?php

namespace App\Http\Controllers;

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

class ApiController extends Controller
{
    //id,pwで認証してtokenを発行
    function login(){

        $credentials = request(['email', 'password']);

        //もし認証エラーなら
        if(!$token = auth('api')->attempt($credentials)){
            return response()->json(['error' => 'Unauthorized'], 401);
        }

        //OKならtoken発行
        return $this->respondWithToken($token);
    }

    //自分の情報返す
    public function me()
    {
        return response()->json(auth()->user());
    }

    //token発行(内部利用)
    protected function respondWithToken($token)
    {
        return response()->json([
            'access_token' => $token,
            'token_type' => 'bearer',
            'expire_in' => auth('api')->factory()->getTTL(),
        ]);
    }
}

TTLは標準では60(分)のようで、config/jwt.phpのttl値で変更できます。

ルートの作成

必要なルートを記述します。login()は(token)認証無し、me()は認証あり。

api.php
<?php

use Illuminate\Http\Request;

Route::middleware('auth:api')->get('/user', function (Request $request) {
    return $request->user();
});

Route::group(['middleware' => 'guest:api'], function(){
    Route::post('/login', 'ApiController@login');
});

Route::group(['middleware' => 'auth:api'], function(){
    Route::get('/me', 'ApiController@me');
});

動作確認

userの登録

めんどくさいのでTinkerを利用します。


php artisan tinker


>>> $user = new App\User;
=> App\User {#2934}
>>>
>>> $user->name = "hoge";
=> "hoge"
>>> $user->email = "hoge@test.com";
=> "hoge@test.com"
>>> $user->password = Hash::make("testtest");
=> "$2y$10$hwJ68OuyQhAlQ1qa5E63HOvH73i2QmZ7NxdmbKZTr3pLLl2i5zUJa"
>>>
>>> $user->save();
=> true

curlで動作確認します。

Tokenリクエスト

まずはTokenのリクエスト。登録したIDとPWを添えてリクエストします。

curl http://localhost:8000/api/login -d email=hoge@test.com -d password=testtest

Tokenリクエストのレスポンス

Tokenが発行されました。テスト環境なのでまんま公開。

{"access_token":"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJodHRwOlwvXC9sb2NhbGhvc3Q6ODAwMFwvYXBpXC9sb2dpbiIsImlhdCI6MTUzODQ2MDU3MywiZXhwIjoxNTM4NDY0MTczLCJuYmYiOjE1Mzg0NjA1NzMsImp0aSI6IkM4M2VUVzBVQUxIRU1MaWoiLCJzdWIiOjEsInBydiI6Ijg3ZTBhZjFlZjlmZDE1ODEyZmRlYzk3MTUzYTE0ZTBiMDQ3NTQ2YWEifQ.I-v9_MgSxgmAtvp0ddkSAIQYDQHAEO2gZIm8xepG0Pg","token_type":"bearer","expires_in":3600}

データリクエスト

取得したtokenをAuthorizationヘッダにBearer tokenと添えてリクエストします。

jsonに対応した動作させるためにAccept: application/jsonも追加しています。

curl -H 'Accept: application/json' -H "Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJodHRwOlwvXC9sb2NhbGhvc3Q6ODAwMFwvYXBpXC9sb2dpbiIsImlhdCI6MTUzODQ2MDU3MywiZXhwIjoxNTM4NDY0MTczLCJuYmYiOjE1Mzg0NjA1NzMsImp0aSI6IkM4M2VUVzBVQUxIRU1MaWoiLCJzdWIiOjEsInBydiI6Ijg3ZTBhZjFlZjlmZDE1ODEyZmRlYzk3MTUzYTE0ZTBiMDQ3NTQ2YWEifQ.I-v9_MgSxgmAtvp0ddkSAIQYDQHAEO2gZIm8xepG0Pg" http://localhost:8000/api/me

データリクエストのレスポンス

情報が取得できました。

{"id":1,"name":"hoge","email":"hoge@test.com","email_verified_at":null,"created_at":"2018-10-02 05:27:27","updated_at":"2018-10-02 05:27:27"}

expire error

expireが来たら、指定したエラーがでるようです。

ミドルウエアではなくControllerで記述したエラーが出る。

{"error":"Unauthorized"}

refresh関連とかも設定できるようですが、とりあえず以上です。

34
34
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
34
34