Laravel: Как скинуть 403, если пользователь вводит ID вручную в маршрут?

Создание приложения (Блог / сообщения). Где только пользователи с авторизацией могут редактировать свои сообщения (которые, конечно, принадлежат только им). Например, сообщение с идентификатором 15 принадлежит конкретному пользователю, поэтому, если он его редактирует, маршрут будет таким

http://localhost:8000/post/15/edit

это правильно.

Но когда пользователь вводит любой другой идентификатор сообщения (который ему не принадлежит) в маршруте, он показывает

http://localhost:8000/post/16/edit

ErrorException (E_NOTICE)
Trying to get property 'user_id' of non-object

Как в этом случае показать неавторизованную страницу?

Это postController

public function edit($id)

{

$post = Post::find($id);

        if (Auth::user()->id == $post->user_id){

        return view('post-edit',compact('post'));
    }else {
        return redirect()->route('home');      

}
}

404 - страница не найдена - вы ищете 403 запрещенный. С этой целью что-то родственное; if ($post_author != $current_user) { exit("Error msg"); } - я не знаю ваших переменных, так что это предположение разумных имен

Can O' Spam 27.06.2018 16:11

Хорошо. Спасибо! а как в таком случае кинуть 403?

user9611583 27.06.2018 16:12

Ошибка, которую вы получаете в этом случае, говорит о том, что переменная, к которой вы обращаетесь в своем коде ($user_id), не существует в классе, из которого вы обращаетесь к ней - убедитесь, что она объявлена ​​и установлена

Can O' Spam 27.06.2018 16:14

Я отредактировал свой вопрос и добавил PostController

user9611583 27.06.2018 16:19
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
1
4
2 965
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Следующий код проверяет, существует ли сообщение (именно поэтому вы получаете сообщение об ошибке Trying to get property 'user_id' of non-object, потому что оно не существует), а затем проверяет, принадлежит ли он пользователю в том же состоянии. Если он недействителен, он прерывается с кодом ошибки 403 UNAUTHORIZED.

public function edit($id)
{
    $post = Post::find($id);
    if (empty($post) || Auth::id() != $post->user_id) {
        abort(403);
    }
    else {
        return view('post-edit',compact('post'));      
    }
}

Вот лучшая версия, которая проверяет, существует ли сообщение с указанным идентификатором, но также и с правильным пользователем, и в противном случае выдает исключение:

public function edit($id)
{
    $post = Post::whereHas('user', function ($q) {
        $q->where('users.id', Auth::id());
    })->findOrFail($id);

    return view('post-edit',compact('post'));      
}

Третья версия, аналогичная второй, но более простая:

public function edit($id)
{
    $post = Post::where('user_id', Auth::id())->findOrFail($id);

    return view('post-edit',compact('post'));      
}

используйте политику авторизации laravel для авторизации пользователей.

php artisan make:policy PostPolicy --model=Post

Эта команда создаст PostPolicy.php в каталоге приложение \ политики. теперь вам нужно зарегистрировать политику в AuthServiceProvider. Поэтому сначала добавьте, например, операторы использования вашей политики и модели.

use App\Post;
use App\Policies\PostPolicy;

затем найдите protected $ политики и в этом массиве зарегистрируйте свою политику. Модель, за которой следует политика.

protected $policies = [
    Post::class => PostPolicy::class,
];

Теперь в вашей Политике, которую мы создали с помощью команды artisan. будет содержать все методы, связанные с CRUD. каждый из них принимает два параметра: один - это пользователь, а второй - модель, которую вы хотите авторизовать, за исключением метода создания. обратите внимание, что вы можете изменить create или другие методы, чтобы принимать больше параметров. тебе решать.

Теперь, например, в вашей политике давайте построим логику для метода обновления.

/**
 * Determine if the given post can be updated by the user.
 *
 * @param  \App\User  $user
 * @param  \App\Post  $post
 * @return bool
 */
public function update(User $user, Post $post)
{
    return $user->id === $post->user_id;
}

Как видите, здесь return Boolean. вы можете настроить методы по своему усмотрению. Далее в вашем методе контроллера. где вы хотите авторизовать пользователя, просто добавьте

public function update(Post $post)
{
    $this->authorize('update', $post);
    // then your logic here.
}

Для создания авторизации достаточно пройти пустой класс

$this->authorize('create', Post::class);

Он принимает два параметра: один - это имя метода авторизации, а второй - модель. Он автоматически получает аутентифицированного пользователя и авторизует пользователя. если не авторизован, то выдает Illuminate\Auth\Access\AuthorizationException, который равен 403.

Также, если вам нужно изменить представление ошибки 403, вам необходимо создать лезвие 403 в

resources/views/errors/403.blade.php

Все хорошо задокументировано в laravel doc.

Дополнительный совет, если вы собираетесь использовать какое-либо значение логического типа данных для возвращаемого из базы данных как tinyint, которое, например, равно 1 или 0.

public function view(User $user, Post $post)
{
    if (! $post->isPrivate) {
       return true;
    }
    return $user->id === $post->user_id;
}

затем обязательно приведите это значение к Boolean в модели, чтобы вернуть его как true или false. потому что это не сработало, когда я развернул свое приложение на общем хостинге. Позже я обнаружил, что он возвращался в виде строки. также версия базы данных была старой.

Другие вопросы по теме