Защитить свои конечные точки Laravel с помощью Passport, чтобы только пользователи, прошедшие проверку подлинности, могли получить к ним доступ, легко. На самом деле, Laravel предоставляет для этого существующее промежуточное ПО, и это объясняется в официальной документации.

Что не так просто и более неясно, так это то, как убедиться, что только не прошедшие проверку подлинности пользователи (или «гости») могут получить доступ к конечной точке. На самом деле, даже поиск в Google не дает хороших результатов в этом отношении, даже если кажется, что в какой-то момент он понадобится почти каждому веб-сайту.

Но зачем вам это нужно?

Некоторым ответ может показаться очевидным, но люди с меньшим опытом могут подумать что-то вроде «Конечно, я не хочу, чтобы зарегистрированные пользователи получали доступ к странице регистрации, но мой интерфейс справится с этим!“.

Никогда не доверяйте вводу пользователя.

Обычно мы видим это правило, когда говорим о формах и фактических «вводах», но, в конце концов, выполнение запроса к API — это тоже ввод пользователя, и ничто не гарантирует вам, что аутентифицированный пользователь не сможет вызвать зарезервированную страницу. гостям.

Это верно для каждого веб-сайта, но помимо этого у вас могут быть и другие причины для этого, например, раскрытие общедоступного API, полное делегирование уровня авторизации вашему серверу и т. д.

Решение

Во-первых, я сказал, что это не так просто, как сделать наоборот, но если вы действительно хотите, есть очень простое решение проверки того, что пользователь не аутентифицирован непосредственно в вашем методе контроллера:

use Illuminate\Support\Facades\Auth;
if (!Auth::check()) {
    // The user is a guest
}

Это работает, но по нескольким причинам это плохое решение:

  1. Ваш контроллер не предназначен для аутентифицированных пользователей/гостей, и у вас, скорее всего, будет if / else, что сделает его менее читаемым.
  2. Легче совершить ошибку и забыть включить условие в один из ваших контроллеров, что может создать проблему безопасности.
  3. Аутентификация проверяется после авторизации, что может привести к выдаче 500 (например, если ваш уровень авторизации проверяет свойства пользователя), засорению ваших журналов и негативному взаимодействию с пользователем.

Решение!

Laravel предоставляет систему под названием Middlewares для обработки аутентификации и авторизации, они в основном перехватывают запрос, сделанный пользователем, и остаются до того, как запрос достигнет вашего контроллера.

namespace App\Http\Middleware;
use Closure;
use Illuminate\Support\Facades\Auth;
class DenyIfAuthenticated {
    /**
    * Handle an incoming request.
    *
    * @param  \Illuminate\Http\Request  $request
    * @param  \Closure  $next
    * @param  string|null  $guard
    * @return mixed
    */
    public function handle($request, Closure $next, $guard = null) {
        if (Auth::guard($guard)->check()) {
            abort(401);
        }
        return $next($request);
    }
}

Этот файл должен находиться в папке app/Http/Middleware.

Сам код очень прост, мы просто получаем пользователя и check(), если он аутентифицирован, и в этом случае мы прерываем запрос с кодом ошибки HTTP 401 Unauthorized. В противном случае мы просто передаем запрос следующему Middleware (или контроллеру, если он последний).

Осталось всего два шага, один из которых — зарегистрировать это Middleware в приложении. Это просто делается путем добавления промежуточного ПО в переменную $routeMiddleware в файле App/Http/Kernel.php и присвоения ему нужного идентификатора:

protected $routeMiddleware = [ 
    ...
    'auth.deny' => \App\Http\Middleware\DenyIfAuthenticated::class
];

Это позволяет вам перейти к следующему шагу, сообщив Laravel, что « auth.deny » — это существующее ПО промежуточного слоя.

Этот последний шаг — перейти к вашему файлу маршрутов и использовать промежуточное ПО, как и любое другое, точно так же, как промежуточное ПО « auth ».

Route::group(['middleware' => ['auth.deny:api']], function () {
    Route::resource('users', 'UserController', ['only' => ['create', 'store']]);
});

Это защитит методы создания и хранения для вашего UserController и выдаст ошибку 401, если пользователь уже аутентифицирован!

Первоначально опубликовано на https://www.mindflash.org 10 марта 2020 г.