이전 포스트까지 게시글의 수정과 삭제 로직을 구현하며 CRUD의 기능을 전부 완성했다.
하지만 남의 글도 수정하거나 삭제할 수 있는 치명적인 문제가 남아있었다.
오늘은 PostPolicy 파일을 생성해서 글의 작성자만 글을 수정하거나 삭제할 수 있도록 방어벽을 세워보겠다.
이전 포스트
Laravel, CRUD 글 삭제 기능 구현
다른 사용자의 글을 수정이나 삭제할 수 있었던 문제 해결 · 4th-avenue/laravel13@f864705 · GitHub
전체적인 코드 수정은 이 깃허브 링크를 통해서 확인할 수 있다.
PostPolicy를 생성하는 명령어
make bash #컨테이너 안으로 들어간다.
php artisan make:policy PostPolicy --model=Post
VSCode의 터미널에서 이 명령어들을 실행한다.
그러면 app/Policies 폴더에 PostPolicy.php 파일이 생성된다.
이 파일은 특정 데이터(여기서는 Post)에 대한 사용자들의 권한 부여를 담당하는 파일이다.
--model=Post 옵션을 붙이면 라라벨 엔진이 Post 모델을 기반으로 한 CRUD(생성, 조회, 수정, 삭제) 관련 권한 검증 메서드들을 파일 내부에 자동으로 채워준다.
이 옵션을 빼면 아무런 메서드가 없는 빈 클래스 파일만 생성되므로, 생산성을 위해 반드시 이 옵션을 붙여서 생성하도록 하자.
PostController에 추가할 코드들
PostController.php의 edit와 update 메서드에 추가할 코드
Gate::authorize('update', $post);
edit 메서드와 update 메서드 내부의 가장 상단에 이 코드를 추가한다.
Gate::authorize() 메서드는 Laravel의 권한 게이트 시스템을 사용하여 사용자의 권한을 검사하는 데 사용된다.
edit와 update 메서드에 들어간 위의 코드는 update 정책 메서드가 정의된 PostPolicy 파일을 참조해서 현재의 사용자가 PostPolicy의 update 메서드에서 정의된 권한을 가지고 있는지 확인한다.
update 메서드에 이 코드를 넣으면 권한이 없는 사용자가 글의 수정 버튼을 클릭하면 403 에러가 뜨게 되고, edit 메서드에 이 코드를 넣으면 권한이 없는 사용자가 글 수정 페이지로 이동하는 것도 차단한다.
PostController.php의 destroy 메서드에 추가할 코드
Gate::authorize('delete', $post);
마찬가지로 destroy 메서드 내부의 가장 상단에 이 코드를 추가한다.
설명은 위와 같다.
use Illuminate\Support\Facades\Gate;
Gate를 임포트Import 하는 것도 잊지 말자.
여기까지 저장한 다음에 글을 수정하거나 삭제하려고 하면 이렇게 403 에러가 뜨게 된다.
남이 쓴 글뿐만 아니라 내가 쓴 글도 수정하거나 삭제할 수 없다.
왜냐하면 현재 PostPolicy의 모든 메서드가 return false; 상태이기 때문이다.
PostPolicy에서 수정과 삭제의 권한 부여
PostPolicy.php에 추가할 코드
return $user->id === $post->user_id;
update와 delete 메서드의 return false;를 삭제하고 이 코드를 넣자.
이 코드는 로그인한 유저의 ID와 글을 쓴 유저의 ID가 일치할 때만 true를 반환한다.
PostPolicy에는 update와 delete 메서드 이외에도 여러 메서드들이 있다.
각 메서드의 역할은 다음과 같다.
- viewAny: 사용자가 전체 글 목록을 조회할 권한이 있는지 검증한다. (예: 특정 등급 회원만 목록을 보게 할 때)
- view: 사용자가 특정 글(
$post)을 상세 조회할 권한이 있는지 검증한다. (예: 비밀글 기능) - create: 사용자가 새로운 글을 작성할 권한이 있는지 검증한다. (예: 차단된 유저의 글쓰기 금지)
- update: 사용자가 이 특정 글을 수정할 수 있는지 검증한다.
- delete: 사용자가 이 특정 글을 삭제할 수 있는지 검증한다.
- restore: 사용자가 이미 삭제되어 휴지통에 가 있는 특정 게시글을 다시 원상태로 복구할 권한이 있는지 검증한다. (예: 자신이 썼다가 지운 글은 자기 자신만 복구 가능 or 관리자(Admin)만 복구 가능)
- forceDelete: Soft Delete 되어 휴지통에 있는 글을 데이터베이스에서 완전히 지워버리는 영구 삭제 권한이 있는지 검증한다. 이 메서드를 통과하여 처리가 완료되면 데이터가 복구 불가능한 상태로 디스크에서 날아간다.
restore와 forceDelete 메서드는 Soft Delete 기능과 연관된 권한 검증 메서드다.
아직 Soft Delete에 대해서 설명한 적이 없는데, 다음에 언젠가 다룰 예정이다.
여기까지 저장하면 이제 본인이 쓴 글만 수정하거나 삭제할 수 있게 된다.
본인의 글만 드롭다운 메뉴가 보이도록 index.blade.php 수정
@canany(['update', 'delete'], $post)
<x-dropdown>
<x-slot name="trigger">
{{-- 생략 --}}
</x-slot>
</x-dropdown>
@endcanany
드롭다운 메뉴 전체를 @canany(['update', 'delete'], $post)와 @endcanany로 감싼다.
@canany 디렉티브는 여러 권한 중 하나라도 현재 사용자에게 있으면 블레이드 블록의 내용을 렌더링 한다.
즉, update나 delete 권한 중 하나라도 사용자에게 있으면 블록이 렌더링 된다.
저장하고 브라우저를 확인하면, 본인의 쓴 글의 미트볼 메뉴(드롭다운 메뉴)만 표시되는 걸 볼 수 있다.
Authorization | Laravel 13.x - The clean stack for Artisans and agents
이번 포스트에서 다룬 내용 외에, 라라벨의 권한 부여에 대한 내용은 이 공식 문서를 통해 확인할 수 있다.

0 Comments
댓글 쓰기
🔸 댓글은 블로그 운영자의 승인 후에 블로그에 표시됩니다.
🔸 비로그인 방문자 분께서는 '익명'보다 이름/URL로 댓글을 남겨주시면 감사하겠습니다. (URL은 생략 가능합니다.)
🔸 구글 로그인 방문자는 '알림 사용'에 체크를 하시면, 남겨주신 댓글에 대한 답글 알림을 메일로 받아볼 수 있습니다. 📩