10
11

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

GraphQL(lighthouse)+jwt認証 in laravel6

Posted at

概要

laravel6での動作確認をそれぞれしつつGraphQLでjwt認証を実装してみました。
備忘録。

環境

  • laravel 6.3.0
  • lighthouse 4.5
  • jwt-auth

インストール

lighthouse

composer require nuwave/lighthouse

laravel-graphql-playground

開発に便利なplaygroundもいれる

composer require mll-lab/laravel-graphql-playground

jwt-auth

composer require tymon/jwt-auth ^1.0.0

^1.0.0じゃないと入ってくれない
ドキュメント要チェック

入れた結果

composer.json

    "mll-lab/laravel-graphql-playground": "^1.1",
    "nuwave/lighthouse": "^4.5",
    "tymon/jwt-auth": "^1.0.0"

lighthouseとgraphql-playgroundの初期設定

lighthouse

参照: https://lighthouse-php.com/4.5/getting-started/installation.html

  • 設定ファイルを作成
# providerの場所が古いバージョンとは変わっているので注意 ドキュメントを参考に
# config/lighthouse.php
php artisan vendor:publish --provider="Nuwave\Lighthouse\LighthouseServiceProvider"

laravel-graphql-playground

  • 設定ファイルとviewを作成
# config/graphql-playground.php
php artisan vendor:publish --provider="MLL\GraphQLPlayground\GraphQLPlaygroundServiceProvider"

/graphql-playgroundにアクセスすると実行画面が表示される
playground.png

jwt-authの初期設定

  • 設定ファイル
# config/jwt.php
php artisan vendor:publish --provider="Tymon\JWTAuth\Providers\LaravelServiceProvider"
  • 秘密鍵の作成
# .envに追加される
php artisan jwt:secret

jwt-authで認証するModelを作成

API認証でjwtを使うために、JWTSubjectを認証するモデルに実装する。
今回はデフォルトのUserモデルを認証に使う。
implementsしてgetJWTIdentifiergetJWTCustomClaimsの2つのメソッドを定義

<?php

namespace App;

// ~略~
use Tymon\JWTAuth\Contracts\JWTSubject;

class User extends Authenticatable implements JWTSubject
{
   // ~略~
   
    // add
    public function getJWTIdentifier()
    {
        return $this->getKey();
    }
    
    // add
    public function getJWTCustomClaims()
    {
        return [];
    }

}
  • getJWTIdentifier
    jwtトークンを取得する

  • getJWTCustomClaims
    jwtトークンにClaim(情報)を追加したい時にはここに追記する

// 例
public function getJWTCustomClaims()
{
    return [
        'email' => $this->email
    ];
}

config/auth.phpの修正

Guardの設定を変更

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

    'api' => [
        'driver' => 'jwt', // add
        'provider' => 'users',
        // 'hash' => false, つかわない
    ],
],

ログインするクエリを作成

php artisan lighthouse:query Login

app/GraphQL/Queriesに作成されます。

認証ロジックはあっさりとこんな感じにしてみました。
$argsにパラメータが入ってきます。
成功したらaccess_tokenを返す。

<?php

namespace App\GraphQL\Queries;

use GraphQL\Type\Definition\ResolveInfo;
use Nuwave\Lighthouse\Support\Contracts\GraphQLContext;

class Login
{
    public function __invoke($rootValue, array $args, GraphQLContext $context, ResolveInfo $resolveInfo)
    {
        if (!$token = auth('api')->attempt(['email' => $args['email'], 'password' => $args['password']])) {
            return ['error' => 'Unauthorized'];
        }
        return ['access_token' => $token];
    }
}

schemaに定義

graphql/schema.graphqlに記述する。
デフォルトで色々書いてありますが、それは置いておいて以下のように定義してみる。
@middlewareディレクティブでミドルウェアを定義することが出来る。
ログインなのでguest:apiミドルウェアを適用。

type Query {
    login(email: String! password: String!): LoginData @middleware(checks: ["guest:api"])
}

# 返ってくるデータのスキーマ
type LoginData {
    access_token: String
    error: String
}

ログインする

クエリを叩く

/graphql-playgroundにて

{
  login(email: "test@example.org" password: "password") {
    access_token
    error
  }
}

実行

結果

成功

{
  "data": {
    "login": {
      "access_token": "ここにトークン",
      "error": null
    }
  }
}

失敗

{
  "data": {
    "login": {
      "access_token": null,
      "error": "Unauthorized"
    }
  }
}

認可ルートを設定

@middlewareディレクティブを使用してauth:apiルートを定義

type Query {
    login(email: String! password: String!): LoginData @middleware(checks: ["guest:api"])
    users: [User!]! @all @middleware(checks: ["auth:api"])
}

HTTP HEADERSでアクセストークンを渡す

{
    "Authorization": "Bearer アクセストークン"
}

結果
g.png

おわり

schema.graphqlを変更したら叩く

php artisan lighthouse:clear-cache
10
11
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
10
11

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?