Laravel 인증을 위한 모델 이외의 매개변수 제공

10775 단어 PHPLaravel

이 문장에 관하여


Laravel #2 Advent Calendar 2019 - Qiita14일째 보도입니다.
제목 그대로지만 의외로 사용되지 않았다는 생각에 기사를 쓰기로 했다.

입문


환경

  • Laravel 6.6.0
  • 5.x도 마찬가지다.

    정책 정보


    이것은 사용자가 특정 모델에 대해 조작 권한이 있는지 판단하는 메커니즘으로 공식 문서에 다음과 같은 사용 예가 있다.
    class PostPolicy {
        public function update(User $user, Post $post) {
            return $user->id === $post->user_id;
        }
    }
    
    호출자
    class PostController extends Controller {
        public function update(Request $request, Post $post) {
            $this->authorize('update', $post);
        }
    }
    
    이렇게
    이 구조를 이용하는 장점은
  • 전달된 모델의 실례에 따라 전략류를 적절하게 선택한다
  • 자동 귀속 사용자 실례 (기본값은 현재 로그인한 사용자) 입니다
  • 권한이 없는 상황에서 임의로 403 오류로 설정합니다
  • 근처야?
    권한 관리가 복잡한 응용 프로그램이라면 응용 프로그램이 인가 기구를 단독으로 설치하는 것이 유연하기 때문에 억지로 사용할 필요는 없지만 팀의 정책에 달려 있다.

    용례

  • 다른 모델의 상태가 필요합니다
  • 정적 권한표 같은 녀석이 있다
  • 동적으로 전략을 바꾸고 싶다
  • 나는 대충 생각난 물건을 하나 들었는데, 기본적으로 모두 같다.

    결론


    수조에서authorize 방법에 파라미터를 전달하면 정책의 모든 방법은 확산 연산자로 전개되기 때문에 복잡한 권한 수여 규칙을 처리할 수 있습니다.
    호출 쪽에서 이렇게 부르면...
    $this->authorize('update', [$mainModel, $subModel]);
    
    그것은 이렇게 전략 방법에 전달된다.
    public function update(User $user, MainModel $main, SubModel $sub) {
    

    사용 예


    1. 다른 모델이 필요한 상태


    사용자와 대상의 모델이 모두 관련되지 않고 다른 모델의 상태가 필요할 때 Controller로 잠시 그 모델의 실례를 얻어authorize 방법(좋은 예가 없기 때문에 적당한 모델명이니 용서해 주십시오)에 맡깁니다.
    public function update(Request $request, Post $post) {
        $someModel = SomeModel::findOrFail($request->some_model_id);
        $this->authorize('update', [$post, $someModel]);
    }
    
    정책 측면에서 다음 상태를 볼 수 있습니다.
    public function update(User $user, Post $post, SomeModel $someModel) {
        return $user->id === $post->user_id && $someModel->acceptable;
    }
    

    2. 정적 권한표 같은 녀석이 있다


    예를 들어 모든 용례는 조작할 수 있는 권한 목록이 있고 맞지 않으면 튕긴다.
    사용 상황에서 결정(또는 일부 규칙에 따라 데이터베이스에서 가져오기)
    class UpdateTask extends UseCase {
        public function validRoles(): array {
            return [Role::Admin, Role::Wheel];
        }
        public function invoke() {...}
    }
    
    이렇게 권한이 있는 목록은 아래와 같이authorize에 넘겨줍니다.
    public function update(UpdateTask $useCase, Post $post) {
        $this->authorize('update', [$post, $useCase->validRoles()]);
    }
    
    전략적으로는 이렇다.
    public function update(User $user, Post $post, array $roles) {
        return $user->hasRole($roles) || $user->id === $post->user_id;
    }
    

    3. 동적 교체 정책


    모든 용례는 자신의 인정 규칙(함수)이 있고 어떤 규칙으로 그 사람을 동태적으로 생성한다.
    class UpdateTask extends UseCase {
        public function authorizeRule(): \Closure {
            return function (User $user, Task $task): bool {
                // ...
            };
        }
        public function invoke() {...}
    }
    
    호출자
    public function update(UpdateTask $useCase, Post $post) {
        $this->authorize('update', [$post, $useCase->authorizeRule()]);
    }
    
    에서 원하는 벽 유형을 선택합니다.
    public function update(User $user, Post $post, \Closure $rule) {
        return $rule($user, $task);
    }
    
    여기까지 와서 저는 전략을 사용할 필요가 없다고 생각했지만 인정하는 구조 자체가 라벨에 맡기고 역 논리는 역 모델에 맡기면 이런 분담도 쉽게 할 수 있기 때문에 연구할 필요가 있다고 생각합니다.

    끝내다


    만약 상술한 열거 이외에 사용 사례가 있다면 평론란에서 저에게 알려주세요

    좋은 웹페이지 즐겨찾기