Help us understand the problem. What is going on with this article?

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

More than 1 year has passed since last update.

環境

  • 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が作れます。

tkt989
AndroidやiOSでアプリを作っています 仕事は加えてWeb系もしてます
http://profile.tkt989.info
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした