Создание приложения (Блог / сообщения). Где только пользователи с авторизацией могут редактировать свои сообщения (которые, конечно, принадлежат только им). Например, сообщение с идентификатором 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');
}
}
Хорошо. Спасибо! а как в таком случае кинуть 403?
Ошибка, которую вы получаете в этом случае, говорит о том, что переменная, к которой вы обращаетесь в своем коде ($user_id), не существует в классе, из которого вы обращаетесь к ней - убедитесь, что она объявлена и установлена
Я отредактировал свой вопрос и добавил PostController






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