Laravel 'can' middleware возвращает ошибку 500 "Это действие не авторизовано" - PullRequest
1 голос
/ 07 февраля 2020

Я пытаюсь создать сайт на основе laravel framework. Я застрял в разрешении контроля с политикой. Это мой код: + Политики Регистрация в App\Providers\AuthServiceProvider:

class AuthServiceProvider extends ServiceProvider
{
    protected $policies = [
        User::class => UserPolicy::class,
        Category::class => CategoryPolicy::class
    ];

    public function boot()
    {
        $this->registerPolicies();

        try {
            Permission::all()->each(function($permission) {
                Gate::define($permission->name, function ($user) use($permission) {
                    return $user->hasPermission($permission->name);
                });
            });
        } catch (\Exception $e) {
            Log::notice('Unable to register gates. Either no database connection or no permissions table exists.');
        }
    }
}
  • Политика пользователя в App\Policies\UserPolicy
class UserPolicy
{
    use HandlesAuthorization;

    public function viewAny(User $user)
    {
        return true;
    }

    public function view(User $user, User $target_user)
    {
        return $user->id === $target_user->id;
    }

}
  • Маршрут API в routes/api.php
Route::get('/users', 'Api\UserController@getUsers')->middleware('can:view-users');
Route::get('/users/{user_id}', 'Api\UserController@getUser')->middleware('can:view-users');
Route::put('/users/{user_id}', 'Api\UserController@updateUser')->middleware('can:edit-users');
  • Контроллер пользователя в App\Http\Controllers\Api\UserController
    public function getUsers(UserRequest $request) {
        $users = $this->userRepository->getAll();
        $this->authorize('view', $user);
        return response($users, 200);
    }

    public function getUser(UserRequest $request, $user_id) {
        $user = $this->userRepository->find($user_id);
        $this->authorize('view', $user);
        return response($user, 200);
    }
  • Когда я пытаюсь получить данные, используя 2 URL выше, он выдал ошибку 500 Internal Server Error, даже когда пользователь прошел аутентификацию:
{
    "error": "This action is unauthorized."
}
  • Я попытался зарегистрировать результат и обнаружил, что ошибка происходит из промежуточного программного обеспечения can или Illuminate\Auth\Middleware\Authorize.

Строка кода:

$this->gate->authorize($ability, $this->getGateArguments($request, $models)); в handle() Ошибка выброса функции выше.

  • После нескольких часов поиска я не смог найти решение.

Кто-нибудь может указать на мою ошибку?

Ответы [ 2 ]

0 голосов
/ 11 февраля 2020

решаемая. После нескольких часов чтения исходного кода в библиотеке я разобрался с проблемой. Я использовал api охранник для моего приложения без passport модуля. Таким образом, переменная $userResolver в классе Illuminate\Auth\Access\Gate не может быть установлена ​​для аутентифицированного пользователя и получила значение null. Чтобы решить эту проблему, я создал собственное промежуточное программное обеспечение Authorize вместо laravel middleware Authorize и использую Auth::guard('api')->user() для аутентификации пользователя.

0 голосов
/ 07 февраля 2020

измените ваш обработчик. php как

<?php

namespace App\Exceptions;
use Exception;
use Illuminate\Auth\AuthenticationException;
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;

class Handler extends ExceptionHandler
{
    /**
     * A list of the exception types that are not reported.
     *
     * @var array
     */
    protected $dontReport = [
         \Illuminate\Auth\AuthenticationException::class,
        \Illuminate\Auth\Access\AuthorizationException::class,
        \Symfony\Component\HttpKernel\Exception\HttpException::class,
        \Illuminate\Database\Eloquent\ModelNotFoundException::class,
        \Illuminate\Session\TokenMismatchException::class,
        \Illuminate\Validation\ValidationException::class,
        //
    ];

    /**
     * A list of the inputs that are never flashed for validation exceptions.
     *
     * @var array
     */
    protected $dontFlash = [
        'password',
        'password_confirmation',
    ];

    /**
     * Report or log an exception.
     *
     * @param  \Exception  $exception
     * @return void
     */
    public function report(Exception $exception)
    {
        parent::report($exception);
    }

    /**
     * Render an exception into an HTTP response.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Exception  $exception
     * @return \Illuminate\Http\Response
     */
    public function render($request, Exception $exception)
    {
        return parent::render($request, $exception);
    }

    protected function unauthenticated($request, AuthenticationException $exception)
    {
        if ($request->expectsJson()) {
         $arr = array("status" => 401, "message" =>"Unauthorized access", "data" => (object)array());
             return \Response::json($arr);
        }
        return redirect()->guest('login');
    }   
}
...