16
17

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.

Laravel5でJWT+Twitter OAuthの認証機能をつくる 2/3

Last updated at Posted at 2015-08-22

認証機能のある、APIサーバーを作ろうとしたときにJWT(Json Web Token)という仕組みが使えそうだったので、
Laravel5で実装してみました。

Laravel5でJWT+Twitter OAuthの認証機能をつくる 1/3
Laravel5でJWT+Twitter OAuthの認証機能をつくる 2/3 ← いまここ
Laravel5でJWT+Twitter OAuthの認証機能をつくる 3/3

その2ということでJWTを実際につかって動作確認までを説明します。

ルーティング

routes.phpに以下のルーティングを設定

<?php

// 認証後のページ
Route::get('/authenticate', 'AuthenticateController@index');

// 認証処理を行う
Route::post('/authenticate', 'AuthenticateController@auth');

// 認証用のフォームを表示
Route::get('/authenticate/signin', 'AuthenticateController@showSignIn');

Controller

ルーティングで指定した、AuthenticateControllerを作成します。

$ php artisan make:controller AuthenticateController

中身は以下のようにします。

App/Http/Controllers/AuthenticateController.php
<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

use JWTAuth;
use Tymon\JWTAuth\Exceptions\JWTException;

use App\Http\Requests;
use App\Http\Controllers\Controller;

class AuthenticateController extends Controller
{

    /**
     * constructor
     */
    public function __construct(){
        $this->middleware('jwt.auth', ['except' => ['showSignIn', 'auth']]);
    }


    /**
     * Display a listing of the resource.
     *
     * @return Response
     */
    public function index()
    {
        // ログイン中のユーザー取得
        $loginUser = JWTAuth::parseToken()->toUser();
        return response()->json(['user' => $loginUser]);
    }


    /**
     * Show Signin form
     */
    public function showSignIn(){
        return view('authenticate.signin');
    }

    /**
     * Authenticate from email and password
     */
    public function auth(Request $request){
        //
        $credentials = $request->only('email', 'password');
        try {
            // verify the credentials and create a token for the user
            if (! $token = JWTAuth::attempt($credentials)) {
                return response()->json(['error' => 'invalid credentials'], 401);
            }
        } catch (JWTException $e) {
            // something went wrong
            return response()->json(['error' => 'could not create token'], 500);
        }

        return response()->json(compact('token'));
    }
}

Controllerでは大まかに以下の4つの処理を記述しています。

  • コンストラクタ
  • ログイン後のユーザー情報を表示するアクション(index)
  • signin用のフォームを表示するアクション(showSignIn)
  • 認証用のアクション

コンストラクタ

まずコンストラクタでミドルウェアの指定をします。
この指定で、jwt.authを用いた認証を行えるようになります。
exceptで認証の対象外にするアクションを指定することができます。
今回はフォームの表示と認証する処理は、ログイン前でも行えるので除外します。

    public function __construct(){
        $this->middleware('jwt.auth', ['except' => ['showSignIn', 'auth']]);
    }

indexアクション

indexアクションは、コンストラクタでexceptされていないため、
tokenが送られていない場合は、以下のJSONが返されます。

{"error":"token_not_provided"}

indexメソッドの中ではJWTAuth::parseTokenでtokenでQueryStringで送られてきたtokenのをparseしています。
そして、toUserメソッドでUserのインスタンスを取得して、それをjsonで表示してます。
簡単ですね!

    public function index()
    {
        // ログイン中のユーザー取得
        $loginUser = JWTAuth::parseToken()->toUser();
        return response()->json(['user' => $loginUser]);
    }

signin用フォームの表示

SignIn用のフォームを表示するための、記載をしています。
bladeテンプレートは後述。

認証用のアクション

authメソッドの中では、SignInフォームから送られてきたemail, passwordが実際に存在するか、認証を行います。
JWTAuth::attempt()で実際に認証が行われ、正常に認証できている場合はJWTのトークンが発行されます。

    /**
     * Authenticate from email and password
     */
    public function auth(Request $request){
        //
        $credentials = $request->only('email', 'password');
        try {
            // verify the credentials and create a token for the user
            if (! $token = JWTAuth::attempt($credentials)) {
                return response()->json(['error' => 'invalid credentials'], 401);
            }
        } catch (JWTException $e) {
            // something went wrong
            return response()->json(['error' => 'could not create token'], 500);
        }

        return response()->json(compact('token'));
    }

コントローラは以上です。

View

作成するViewはsignin用のbladeテンプレートのみです。
今回は、Formヘルパーを使用します。(使用しない人は次の「Formヘルパーのインストール」は読み飛ばしてください)

Formヘルパーのインストール

Laravel4だと標準搭載のFormヘルパーですが、Laravel5では別パッケージとなったようです。

下記サイト様を参考にインストールを行いました。
https://laravel10.wordpress.com/2015/03/08/%E5%88%9D%E3%82%81%E3%81%A6%E3%81%AElaravel-5-16-form%E3%81%AE%E4%BD%9C%E6%88%90/

まずは、Composerでインストールします。

$ composer require laravelcollective/html

そして、config/app.phpに追記します。

config/app.php

  'providers'=> [
   // ・・・
     Collective\Html\HtmlServiceProvider::class,
  ],

  'aliases' => [
   // ・・・
    'Form' => Collective\Html\FormFacade::class,
    'Html' => Collective\Html\HtmlFacade::class
  ]

ヘルパの設定は以上です。

SignInフォーム

SignInフォームを表示するために、以下のようなbladeテンプレートを記述します。

resources/views/authenticate/signin.blade.php
{!! Form::open(array('url' => 'authenticate', 'method' => 'post')) !!}
<div class="form-group">
    {!! Form::label('email', 'メールアドレス') !!}
    {!! Form::text('email', null, ['class' => 'form-control']) !!}
</div>
<div class="form-group">
    {!! Form::label('password', 'パスワード') !!}
    {!! Form::password('password', null, ['class' => 'form-control']) !!}
</div>
<div class="form-group">
    {!! Form::submit('Signin', ['class' => 'btn btn-primary form-control']) !!}
</div>
{!! Form::close() !!}

詳しい使い方はAPIリファレンスを参考にしてみてください。
http://laravelcollective.com/docs/5.1/html

動作確認

ここまできたら、実際に動作確認してみます。

以下の3点が確認できれば、とりあえずは認証機能として動作するかとおもいます。

  • /authenticate にアクセスして、token_not_providedではじかれるかチェック
  • /authenticate/signinでフォームにDBに登録したものを入力して、tokenが取得できるか
  • 取得できたtokenをQueryStringのパラメータに入れて、/authenticateにアクセスし、ユーザー情報が取得できるか

まずはブラウザで、http://DOMAIN_NAME/authenticate にアクセスしてみます。
(DOMAIN_NAMEは適宜読み替えてください。自分の環境だと http://homestead.app のようになってます。)

スクリーンショット 2015-08-23 0.18.19.png

たしかに、tokenが無いよと怒られてます。

次に、/authenticate/signinにアクセスしてみます。

スクリーンショット 2015-08-23 0.22.39.png

上のようなフォームが表示されれば成功です。
では、その1で用意したユーザーの情報をいれてみます。
email: jwt-test@example.com
password: 'password'

スクリーンショット 2015-08-23 0.28.22.png

送信すると、、、

スクリーンショット 2015-08-23 0.28.48.png

tokenが取得できました!

このtokenをURLにくっつけて/authenticateにアクセスしてみます。

スクリーンショット 2015-08-23 0.31.06.png

ちゃんと、ユーザー情報を取得することができました。

実際に使う場合は、APIをたたく側で認証後に発行されたtokenを保持して、APIにアクセスするタイミングでtokenを一緒に送ってもらい認証する形になると思います。

以上でJWTで認証するところまでできました。

次回

次はTwitter OAuthでも同様に認証をしてみたいと思います。

16
17
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
16
17

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?