Laravelのmiddlewareを使ってajax以外のアクセスを禁止する



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']);

 

Summary

以上が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

 

この記事のカテゴリ
プログラミング

この記事に付けられているタグ



その他の運営サービス

最新の記事