IBM developerWorks Slim マイクロフレームワークで REST アプリケーションを作成するを参考に、SlimPHPのスケルトンアプリから作成します。コードはSlimPHP3用に書き換えています。
SlimPHP:Slim マイクロフレームワークで REST アプリケーションを作成する(3)PUT/DELETE - tanaka's Programming Memo からの続きです。
ルート・ミドルウェアによる認証の追加
これまで src/routes.php にアクセスしてきたルートパターンに応じたコールバックを設定してきました。設定したルートが発動する前にミドルウェアとして処理を加えることができます。
ミドルウェアを使用して、独自の認証メソッドを実装します。カスタム認証メソッドを介してリクエストを渡すことで、APIリクエストが認証されてからでないと処理されないようにします。
SlimPHP3のミドルウェアについては、SlimPHPの公式サイトを意訳した SlimPHP:ミドルウェアの使い方 - tanaka's Programming Memo にまとめてあります。
単純な認証関数を作成して、それをミドルウェアとしてGETリクエストハンドラーに追加してみます。
認証用のミドルウェアクラスCAuthenticateを作成して、その中でユーザーキーのチェックをします。失敗したらステータスコード401を返してそのまま処理を終了するのでreturnします。成功した場合は、次のミドルウェアを呼び出して、最終的にアプリケーションの処理を実行します。仕様として、必ずレスポンスのインスタンスをreturnします。
src/middleware.phpを開いて、以下を入力します。
<?php // 認証用ミドルウェアを定義 class CAuthentication { public function __invoke($request, $response, $next) { if ($this->validateUserKey("user", "pass") === false) { // 失敗時は、許可なしを返す return $response->withStatus(401); } // 認証が通ったので、処理を継続する return $next($request, $response); } // 認証本体 function validateUserKey($uid, $key) { // ここに、認証処理を入れます。成功時はtrue、失敗時はfalseを返します return false; } }
作成した認証用ミドルウェアをGETルートハンドラーに設定します。
src/routes.phpを開いて、 $app->get('/articles', ・・・から始まるルートを探して、以下のように最後にミドルウェアを追加します。
// articlesへのルートを設定する $app->get('/articles', function($request, $response, $args) { // 一覧を取得 $articles = R::find('articles'); // JSONを返すためのヘッダを設定 $newresp = $response->withHeader('Content-Type', 'application/json'); // JSONでエンコードした結果を返す echo json_encode(R::exportAll($articles)); // responseを渡す return $newresp; })->add(new CAuthentication());
$app->get(・・・)->add(new ミドルウェアクラス); とすることで、そのルートの処理にミドルウェアを登録することができます。
動作テスト
Firefoxなどで、Firebugなどの開発ツールを表示して、 http://0.0.0.0:8080/articles にアクセスしてください。画面には何も表示されず、開発ツールのネットワークのステータスとして、401が返ってきます。
他のリクエスト、例えば http://0.0.0.0:8080/articles/1 にはミドルウェアを設定していないので、実行することができます。
middleware.phpのvalidateUserKey()関数内の return false; の部分を、 return true; に変更すると、 http://0.0.0.0:8080/articles へのアクセスができるようになります。
認証の例
この後、参考元の記事ではCookieを使った例がありますが、関数が変更になっていることや、実例としてあまり役に立ちそうになかったので省略します。認証周りに関しては、 Sentinel Manual :: Cartalyst の採用を検討しています。