Laravel: Как скинуть 403, если пользователь вводит идентификатор вручную в маршрут? - PullRequest
0 голосов
/ 27 июня 2018

Создание приложения (блог / посты). Где только авторизованные пользователи могут редактировать свои посты (какой из них принадлежит только им). Например, сообщение с идентификатором 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

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

Это постКонтроллер

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');      

}
}

Ответы [ 2 ]

0 голосов
/ 27 июня 2018

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

php artisan make:policy PostPolicy --model=Post

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

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

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

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

Теперь в вашей Политике, которую мы создали с помощью команды artisan. будет содержать все методы, связанные с CRUD. каждый из них принимает два параметра, один из которых - Пользователь, а второй - модель, которую вы хотите авторизовать, кроме метода create. обратите внимание, что вы можете изменить 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;
}

Как вы можете видеть, верните 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;
}

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

0 голосов
/ 27 июня 2018

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

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'));      
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...