Исключение AuthorizationException
Исключение AuthorizationException принадлежит пространству имён Illuminate\Auth\Access и используется в Laravel для обозначения ситуаций, когда текущий аутентифицированный пользователь не авторизован для выполнения запрошенного действия. Это исключение автоматически генерируется при срабатывании механизма Gate, Policy или при вызове метода authorize в контроллере. В ответ на это исключение Laravel по умолчанию возвращает HTTP-ответ со статусом 403 (Forbidden) или перенаправляет пользователя на страницу входа, в зависимости от того, выполняется ли запрос через API или через веб-интерфейс. Исключение содержит дополнительную информацию, такую как сообщение об ошибке и код, которые помогают разработчику понять причину отказа в доступе.
Синтаксис
<?php
use Illuminate\Auth\Access\AuthorizationException;
// Выброс исключения вручную
throw new AuthorizationException($message, $code);
?>
Исключение AuthorizationException принимает два необязательных параметра: сообщение с описанием ошибки и код ошибки. В большинстве случаев это исключение не выбрасывается вручную, а генерируется автоматически через фасад Gate или метод authorize.
Пример автоматической генерации через Gate
Создадим Gate для проверки прав на обновление статьи и вызовем его через метод authorize в контроллере:
<?php
namespace App\Providers;
use App\Models\Article;
use App\Models\User;
use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;
use Illuminate\Support\Facades\Gate;
class AuthServiceProvider extends ServiceProvider
{
public function boot(): void
{
Gate::define('update-article', function (User $user, Article $article) {
return $user->id === $article->user_id;
});
}
}
?>
<?php
namespace App\Http\Controllers;
use App\Models\Article;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Gate;
class ArticleController extends Controller
{
public function update(Request $request, Article $article)
{
Gate::authorize('update-article', $article);
$article->update($request->all());
return redirect()->route('articles.index');
}
}
?>
Если пользователь попытается обновить статью, которую он не создавал, будет выброшено исключение AuthorizationException с сообщением "This action is unauthorized.":
"Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException: This action is unauthorized."
Пример с использованием Policy
Создадим Policy для модели Article и используем его в контроллере через метод authorize:
<?php
namespace App\Policies;
use App\Models\Article;
use App\Models\User;
class ArticlePolicy
{
public function view(User $user, Article $article): bool
{
return $user->id === $article->user_id || $user->is_admin;
}
public function delete(User $user, Article $article): bool
{
return $user->id === $article->user_id && $article->status === 'draft';
}
}
?>
<?php
namespace App\Http\Controllers;
use App\Models\Article;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
class ArticleController extends Controller
{
public function show(Article $article)
{
$this->authorize('view', $article);
return view('articles.show', ['article' => $article]);
}
public function destroy(Article $article)
{
$this->authorize('delete', $article);
$article->delete();
return redirect()->route('articles.index');
}
}
?>
При попытке просмотра статьи другим пользователем будет выброшено исключение:
"Illuminate\Auth\Access\AuthorizationException: This action is unauthorized."
Пример обработки исключения
Перехватим исключение AuthorizationException и обработаем его в контроллере, вернув кастомный ответ:
<?php
namespace App\Http\Controllers;
use App\Models\Article;
use Illuminate\Auth\Access\AuthorizationException;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Gate;
class ArticleController extends Controller
{
public function edit(Article $article)
{
try {
Gate::authorize('update-article', $article);
return view('articles.edit', ['article' => $article]);
} catch (AuthorizationException $e) {
return redirect()
->route('articles.index')
->with('error', 'You do not have permission to edit this article.');
}
}
}
?>
Если пользователь не авторизован для редактирования статьи, он будет перенаправлен с сообщением об ошибке:
"Redirecting to articles.index with flash message: You do not have permission to edit this article."
Пример с кастомным сообщением
При вызове метода authorize можно передать вторым параметром кастомное сообщение, которое будет использовано в исключении:
<?php
namespace App\Http\Controllers;
use App\Models\Article;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Gate;
class ArticleController extends Controller
{
public function publish(Article $article)
{
Gate::authorize('publish', $article, 'Only the author can publish this article.');
$article->update(['status' => 'published']);
return redirect()->route('articles.index');
}
}
?>
В случае неудачи будет выброшено исключение с указанным сообщением:
"Illuminate\Auth\Access\AuthorizationException: Only the author can publish this article."
Смотрите также
-
исключение
AuthenticationException,
которое выбрасывается при отсутствии аутентификации -
исключение
AccessDeniedHttpException,
которое является HTTP-обёрткой для AuthorizationException -
метод
render,
который позволяет кастомизировать отображение исключений -
метод
report,
который используется для логирования исключений