PHPのMVCフレームワーク「Laravel」のMiddleware ( ミドルウェア ) を使ってAjax以外からのアクセスを禁止する方法の紹介です。
Webシステムを開発をしていると特定の権限、通信以外を禁止したい場面がよくあります。権限どころではログインしたユーザーのみを許可するAuth ( OAuth含む )が一般的ですね。通信であればAjax( javascriptからの通信 )があります。
っということで、Laravelフレームワーク上でMiddlewareを使ってAjax以外からの通信を弾くようにしましょう!( * Lumenでも可能です )
Laravelにはターミナル上からデフォルトでコードが生成出来るコマンドが用意されているので、それを使います。勿論、手動で作っても問題ありません。
( * Lumen 5.2 にはミドルウェア作成コマンドは用意されていません )
# AjaxOnlyMiddewareというクラスを作成
# app/Http/Middlewareに AjaxOnlyMiddleware.phpというファイルが作成されます
php artisan make:middleware AjaxOnlyMiddleware
// app/Http/Middleware/AjaxOnlyMiddleware.php
namespace App\Http\Middleware;
use Closure;
// コマンドで作成されたクラス
class AjaxOnlyMiddleware
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle($request, Closure $next)
{
/**
* ここに処理を書いていきます
*/
// middlewareをパスした後の処理 *コントローラーに処理が続いたり等
return $next($request);
}
}
コマンドライン上からミドルウェアを作成すると上記のようなコードが作られるので、handleメソッド内に処理を記述していきます。Laravelのコンポーネントの中にはリクエストがajaxか判別する関数が用意されているので、それを使います。
// AjaxOnlyMiddleware内のhandle()内に記述
public function handle($request, Closure $next)
{
// リクエストがajaxではない場合の処理
if (!$request->ajax()) {
// viewを表示させたい場合 view('someView')という風に記述できます。
return 'this request only allowed Ajax.';
}
// ajaxからのアクセスだと、そのまま次の処理に進みます
return $next($request);
}
処理を書き終えれば、次はapp/Http/Kernel.php内に作成したミドルウェアを登録する処理を書きましょう。
// app/Http/Kernel.php
protected $routeMiddleware = [
'auth' => \App\Http\Middleware\Authenticate::class,
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
'ajaxOnly' => \App\Http\Middleware\AjaxOnlyMiddleware::class, // ajaxOnlyという名で登録しました
];
// Lumenであれば bootstrap/app.php内に記述します
$app->routeMiddleware([
'ajaxOnly' => App\Http\Middleware\AjaxOnlyMiddleware::class,
]);
これで作成したミドルウェアが使えるようになりました!実際にroutes内で使う時は下記のようになります。
( 下の処理スニペットはcsrf_tokenを取得させる処理を書いています )
// app/Http/routes.php
/**
* ブラウザでアクセスすると ’this request only allowed Ajax.’というメッセージが表示
* ajax経由でアクセスするとtokenが表示されます
*/
// Laravel, Lumen共通
$app->get('/token', [
'middleware' => 'ajaxOnly',
// 配列にして複数ミドルウェアを適応させることもできます
// 'middleware' => [ajaxOnly', 'auth'],
function () { return csrf_token(); }, ]);
// Laravel 5.2であれば下記のような書き方も可能
$app->get('/token', function() { return csrf_token(); })
->middleware(['ajaxOnly']);
以上がajaxからのアクセス以外のアクセスを弾く処理の説明でした。
上の様な処理やauth以外にも様々なことができます。
例えば、MobileDetectと組み合わせてPC以外の処理を通さないようにしたり ...
( 以前紹介した記事: Laravelでmobile detectプラグイン使う )
public function handle($request, Closure $next)
{
// モバイル端末からのアクセスを通さない
if (\Agent::isMobile()()) {
return 'このページはモバイル端末でアクセスできません。';
}
return $next($request);
}
複数のサービスが動いている時は、緊急メンテナンスが必要な時にサービス全体を止めず 機能の一部分だけを止めたり等。
// middleware
// 'maintenance' という名で登録と仮定
public function handle($request, Closure $next)
{
// メンテナンス中なのでアクセス通さないようにする
return '只今メンテナンス中のため一時的に使用できなくなっています。';
}
// routes.php
$app->post('new_post', [
'name' => 'post',
'middleware' => ['maintenance'], //一時的にサービスの機能を止める
// 'middleware' => ['auth', 'ajaxOnly'], // 普段使い
'uses' => 'PostController@post'
]);
ミドルウェアという概念は面白く、使い方次第で色々なことが出来るでゼヒ×2活用してください!
Laravel: Http Middleware