Как предотвратить прямой доступ к Laravel Routes (т. е. не-ajax-запросы)

В моем проекте я использую Laravel исключительно как бэкэнд API, а весь интерфейс обрабатывается Angular javascript. На данный момент к маршрутам Laravel можно получить прямой доступ, и он выкашливает все данные в формате Json, которые отображаются в браузере. Я хочу наложить на него ограничение, чтобы Laravel отвечал только на запросы Ajax и ничего больше.

Я прочитал этот пост здесь, в котором есть решение для Laravel 4, то есть добавление ограничения в filter.php. Но начиная с Laravel 5.1 фильтры больше не используются, и я считаю, что промежуточное ПО можно использовать для того же. Однако я не уверен, как продолжить изменение решения Laravel 4 в этом ответе SO с фильтра на промежуточное ПО.

Может ли кто-нибудь поделиться своими идеями о том, как предотвратить прямой доступ к маршрутам Laravel 5.1, пожалуйста?

Решение Laravel 4 с использованием filter.php: в filter.php объявите этот фильтр:

Route::filter('isAJAX', function()
{
    if (!Request::AJAX()) return Redirect::to('/')->with(array('route' => Request::path()));
});

Затем поместите все свои маршруты, которые вы хотите использовать только через AJAX, в группу. В ваших маршрутах.php:

Route::group(array('before' => 'isAJAX'), function()
{
    Route::get('contacts/{name}', ContactController@index); // Or however you declared your route

    ... // More routes
});

person Neel    schedule 15.09.2015    source источник


Ответы (1)


Создайте файл промежуточного ПО app/Http/Middleware/OnlyAjax.php со следующим содержимым:

<?php 

namespace App\Http\Middleware;

class OnlyAjax
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, \Closure $next)
    {
        if ( ! $request->ajax())
            return response('Forbidden.', 403);

        return $next($request);
    }
}

Затем зарегистрируйте свое промежуточное ПО в файле app/Http/Kernel.php

<?php namespace App\Http;

use Illuminate\Foundation\Http\Kernel as HttpKernel;

class Kernel extends HttpKernel
{
    /**
     * The application's global HTTP middleware stack.
     *
     * @var array
     */
    protected $middleware = [
        //... your original code
    ];

    /**
     * The application's route middleware.
     *
     * @var array
     */
    protected $routeMiddleware = [
        //... your original code
        'ajax' => \App\Http\Middleware\OnlyAjax::class,
    ];
}

И, наконец, прикрепите промежуточное ПО к любому маршруту или группе маршрутов, которые вы хотите сделать доступными только через AJAX. то есть:

/// File: routes/web.php

// Single route
Route::any('foo', 'FooController@doSomething')->middleware('ajax');

// Route group
Route::middleware(['ajax'])->group(function () {
    // ...
});
person Javi Stolz    schedule 15.09.2015
comment
Это фантастика! Именно то, что мне нужно. Большое спасибо @JaviStolz Это огромная помощь, так как я застрял на этом долгое время. V счастлив :) Сейчас попробую. - person Neel; 15.09.2015
comment
Это можно легко обойти, добавив HTTP-заголовок X-Requested-With: XMLHttpRequest вручную к HTTP-запросам. - person Epoc; 14.06.2016
comment
Другое дело — использовать фильтры cors, чтобы разрешать запросы только из определенного домена вместе с промежуточным ПО isAjax. - person Geoff; 31.01.2018
comment
Также убедитесь, что доступ к маршрутам API осуществляется через токены доступа, например: паспорт, срок действия которого истекает через определенное время. - person Geoff; 31.01.2018