2017-02-06 2 views
0

사용자가 Laravel 5.4에서 자신의 프로필을 볼 수있게하려고합니다. AuthServiceProvider.php에Laravel 정책은 항상 거짓입니다.

UserPolicy.php

public function view(User $authUser, $user) 
{ 
return true; 
} 

등록 정책

protected $policies = [ 
    App\Task::class => App\Policies\TaskPolicy::class, 
    App\User::class => App\Policies\UserPolicy::class 
]; 

경로

Route::group(['middleware' => 'auth'], function() { 
    Route::resource('user', 'UserController'); 
}); 

블레이드 템플릿

@can ('view', $user) 
// yes 
@else 
// no 
@endcan 

UserController.php

public function profile() 
{ 
    return $this->show(Auth::user()->id); 
} 
public function show($id) 
{ 
    $user = User::find($id); 
    return view('user.show', array('user'=>$user,'data'=>$this->data)); 
} 

반환은 '거짓'항상. 컨트롤러에서 정책 양식을 호출하는 것과 같습니다. 어디서 잘못 나니?

답변

2

내 자신의 질문에 답하는 것이 이상하게 느껴지지만 후속 조치없이 질문에 이르게되면 싫어합니다. 이중 그것은 밝혀졌다 확인 후 내가 컨트롤러 기능에 권한 부여를 위해 생성자

public function __construct() 
    { 
    $this->authorizeResource(User::class); 
    } 

과에서 authorizeResource를 제거하고 확인하는 경우

그래서

$this->authorize('view',$user); 

모든 작동합니다. $user을 정책 기능의 매개 변수로 추가했을 때이 부분을 놓쳐 버렸을 것입니다. 따라서 볼 사용자는 authorizeResource 방법으로 전달되지 않습니다.

시간을내어 도와 주셔서 감사합니다.

0

솔루션 :

변경 @can('view', $subject)@can('view', $user)에서 두 번째 매개 변수와 그것을 찾을 작동합니다.

이유 :

당신이 길을 잘못하고있는 때문입니다.

public function view(User $user, $subject){ 
return true; 
} 

그냥 신중하게 정책보기 방법을 보면, 첫 번째 매개 변수는 authenticated user 또는 current user하고 정책 모델을 중심으로 인증 로직을 구성하기 때문에 두 번째 매개 변수는, $subject입니다.

정책은 특정 모델 또는 리소스 주위에 권한 부여 논리를 구성하는 클래스입니다. 예를 들어 응용 프로그램이 블로그 인 경우 게시 모델이 있고 에 해당하는 PostPolicy가 게시 작성 또는 업데이트와 같은 사용자 작업을 승인 할 수 있습니다.

깊은 곳으로 들어가고 싶다면.

/** 
* Resolve the callback for a policy check. 
* 
* @param \Illuminate\Contracts\Auth\Authenticatable $user 
* @param string $ability 
* @param array $arguments 
* @return callable 
*/ 
protected function resolvePolicyCallback($user, $ability, array $arguments) 
{ 
    return function() use ($user, $ability, $arguments) { 
     $instance = $this->getPolicyFor($arguments[0]); 

     // If we receive a non-null result from the before method, we will return it 
     // as the final result. This will allow developers to override the checks 
     // in the policy to return a result for all rules defined in the class. 
     if (method_exists($instance, 'before')) { 
      if (! is_null($result = $instance->before($user, $ability, ...$arguments))) { 
       return $result; 
      } 
     } 

     if (strpos($ability, '-') !== false) { 
      $ability = Str::camel($ability); 
     } 

     // If the first argument is a string, that means they are passing a class name 
     // to the policy. We will remove the first argument from this argument list 
     // because the policy already knows what type of models it can authorize. 
     if (isset($arguments[0]) && is_string($arguments[0])) { 
      array_shift($arguments); 
     } 

     if (! is_callable([$instance, $ability])) { 
      return false; 
     } 

     return $instance->{$ability}($user, ...$arguments); 
    }; 
} 

https://github.com/laravel/framework/blob/5.3/src/Illuminate/Auth/Access/Gate.php#L353가 전달된다 (우리의 경우 모델에서) $ 사용자와 $ 인수와 함께 방법을 호출하는 마지막 행을 참조하십시오. 자신의 프로필을 보는 사용자에 여기

Laravel Docs for Authorization/Policies

+0

답장을 보내 주셔서 감사합니다. 아마도 내 매개 변수 이름이 오해의 소지가 있었을 것입니다. 죄송합니다. 내가 원했던 것은 '인증 된 사용자'를 첫 번째 매개 변수로 전달하고 사용자를 두 번째 매개 변수로 전달하는 것입니다. 나는 나의 컨트롤러에서'$ user'를 패스 한 것을 보여주기 위해 나의 대답''@can ('view', $ user)'에 같은 변수 이름을 사용했다. '$ user' (이전에'$ subject'라고 부름)는 볼 사용자입니다. – sr9yar

1

그냥 다른 접근 방식.

먼저, 내가

public function profile() 
{ 
    $user = Auth::user(); 
    return view('profile', compact('user')); 
} 

이 방법을 수행 profile 기능에 그런 다음

Route::group(['middleware' => 'auth'], function() { 
    Route::get('profile', '[email protected]'); 
}); 

에 대한 경로를 생성합니다 사용자 만 자동으로 자신의 프로필을 볼.

이제 일부 사용자가 다른 사용자의 프로필을 볼 수있게하려면 정책을 사용할 수 있습니다. 왜? 왜냐하면 나는 사용자가 항상 자신의 프로필을 볼 수 있어야한다고 생각하기 때문입니다. 그러나 모든 사용자가 다른 사용자 프로필을 볼 수있는 것은 아닙니다.

+0

답변 해 주셔서 감사합니다. 실제로 나는 부모 사용자가 자신의 프로필 ** 및 ** (보스와 직원과 같은) 자녀 프로필을 보거나 편집 할 수 있도록하고 싶어합니다. 따라서 직원은 자신의 프로필 만 볼 수 있으며 상사는 다른 직원의 직원을 보거나 수정할 수 없습니다. 실제 결과는 내 정책 파일의이 함수가 왜'return true; '라고 썼지 만'false'를 반환하는 이유이기 때문에 나의 예제를 단순화했다. – sr9yar

+0

그런 다음 public function view (User $ parent, User $ 사용자)'; 그것이 차이를 만들 것인지 확실하지 않은 경우. 그러나 시험 할 때 느슨 할 것은 없습니다. – EddyTheDove

+0

아니요. 또한 @if (Auth :: user() -> can ('view', $ user))'와 같은 블레이드 템플릿을 다시 작성해 보았습니다. 구문에 문제가 있다고 생각하지 않습니다. – sr9yar

관련 문제