LoginSignup
94
100

More than 5 years have passed since last update.

Laravel + Jwt Auth で認証付きWebAPIを作る

Last updated at Posted at 2018-03-27

環境

  • PHP7.2
  • Laravel5.5

作るもの

  • /api/login ユーザーとパスワードを送るとトークンが発行される。
  • /api/me ユーザーの情報を返す。トークンが無いとアクセスできない。

認証機能を導入

まずはLaravelに備わっている認証機能を有効にしておきます。

php artisan make:auth
php artisan migrate

これだけでログイン機能ができる。
WebAPIのときに使うのでユーザーを登録しておきましょう。

composerでjwt-authをインストール

jwt-authをLaravelプロジェクトにインストールします。

composer require tymon/jwt-auth 1.0.0-rc2

Laravel5.5>= には1.0以上のjwt-authが必要なのでバージョンを指定します。

次にjwt-authの初期設定を行います。

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

config/jwt.phpが生成されます。

最後に秘密鍵を生成。

php artisan jwt:secret

Userモデルを修正

Userモデルをjwt-authに対応させるため、編集します。

 <?php

 namespace App;

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

-class User extends Authenticatable
+class User extends Authenticatable implements JWTSubject
 {
    ...

+    public function getJWTIdentifier()
+    {
+        return $this->getKey();
+    }
+    public function getJWTCustomClaims()
+    {
+        return [];
+    }
}

guardを修正

guardは認証を管理する仕組みで、デフォルトではwebapiがあります。
webは普通にhtmlからのログインを管理しています。
一方apiは名前の通り、WebAPIのログインです。

jwt-authを使うのでapijwtに変えます。

config/auth.phpを編集

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

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

ApiControllerを生成

次にAPIのコントローラーを作成します。

php artisan make:controller ApiController

app/Http/Controllers/ApiController.phpが生成されます。

以下のように変更しましょう。

<?php

namespace App\Http\Controllers;

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

class ApiController extends Controller
{
    function login() {
        $credentials = request(['email', 'password']);

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

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

    public function me()
    {
        return response()->json(auth()->user());
    }

    protected function respondWithToken($token)
    {
        return response()->json([
            'access_token' => $token,
            'token_type' => 'bearer',
            'expires_in' => auth("api")->factory()->getTTL() * 60
        ]);
    }
}

ログインとユーザー情報を取得するメソッドを作成しました。

routes/api.phpを編集

routesファイルを編集。

<?php

use Illuminate\Http\Request;

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

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

/loginguestを指定して認証がなくてもアクセスできるように、/meはログインしてトークンを送らないとアクセスできないようにしました。

試す

curlで試してみます。
emailpasswordは上のユーザーを登録したときのを指定します。

curl http://<laravel-host>/api/login -d email=hoge@example.com -d password=hoge12345

すると以下のようにトークンを含んだjsonが返ってきます。

{"access_token":"eyJ0eXAiOiJKV2QiLC2hbGciOiJIUzI1NiJ9.eyJpc3MiOiJodHRwOlwvXC9sYXJhdmVsLXRha2FzYW45ODkuYzl1c2Vygy5pb1wvYXBpXC9sb2dpbiIsImlhdCI6MTUyMjE1NTY1OSwiZXhwIjoxNTIyMTU5MjU5xCJuYmYiOjE1MxIxNTU2NTksImp0aSI6Inh6MHRsQ1hHNmgwQ1g3V0UiLCJzdWIiOjEsInBydiI6Ijg3bTBhZjFlZjlmZDE1ODEyZmorYzk3MTUzYTE0ZTBJfDQ3NTQ2YWEifQ.BdoHaKFy8XLOSaTKBOhA1D3i5NPUGzG9E1lsBQefEhs","token_type":"bearer","expires_in":3600}

そしてトークンを使って認証が必要なurlにアクセスしてみます。
AuthorizationヘッダーにBearer: <token>を付けて送信します。

curl -H "Authorization: Bearer eyJ0eXAi...." http://<laravel-host>/api/me

実行すると

{"id":1,"name":"hoge","email":"hoge@example.com","created_at":"2018-03-26 14:33:21","updated_at":"2018-03-26 14:33:21"}

ログインしているユーザーの情報が返ってきました。

これを応用すればユーザー認証ができるWebAPIが作れます。

94
100
1

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
94
100