Edited at

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

More than 3 years have passed since last update.

認証機能のある、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 のようになってます。)

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

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

上のようなフォームが表示されれば成功です。

では、その1で用意したユーザーの情報をいれてみます。

email: jwt-test@example.com

password: 'password'

送信すると、、、

tokenが取得できました!

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

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

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

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


次回

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