이번 포스트에서는 약간 쉬어가는 느낌으로 여러 기능을 구현하지 않고, 딱 두 가지 기능만 구현해 보겠다.
filament 리소스 테이블에서 일괄 삭제 기능을 없애고, 중요한 데이터를 삭제하기 전에는 패스워드를 물어보는 기능을 구현하려고 한다.
이전 포스트
라라벨 SPATIE 권한 관리, 사용자별 글 작성·수정·삭제 제어 및 관리자 전체 권한 부여
Category 삭제 시 비밀번호를 입력해야 삭제되는 기능 구현 · 4th-avenue/laravel13-livewire@2a1a4c7 · GitHub
전체적인 코드 수정은 이 깃허브 링크를 통해서 확인할 수 있다.
filament 리소스 테이블에서 일괄 삭제 기능 없애기
filament 관리자 메뉴에서 Category 리소스 테이블을 캡처했다.
filament 리소스 테이블에는 이렇게 기본적으로 체크박스와 함께 데이터들을 한꺼번에 일괄 삭제하는 기능이 있다.
그런데 한번 정해진 카테고리는 웹사이트를 운영하는 중에 그렇게 자주 바꿀 일이 없다.
특히 여러 카테고리를 한꺼번에 삭제할 일은 더더욱 없다.
그러니 먼저, 혹시라도 그런 실수를 할 가능성을 차단하기 위해서 Category 리소스 테이블에서는 일괄 삭제하는 기능을 없애보겠다.
app/Filament/Resources/Categories/Tables/CategoriesTable.php에서 삭제할 코드
->toolbarActions([
BulkActionGroup::make([
DeleteBulkAction::make(),
]),
])
이 코드를 삭제하면 된다.
라라벨의 Soft Delete 기능에 대해 알아보자. (categories와 articles 테이블 추가)
이전에 articles 테이블을 만들 때, category_id 컬럼에 cascadeOnDelete() 메서드를 사용했다.
그래서 현재, 카테고리가 삭제되면 그 카테고리에 속한 글들도 전부 자동으로 삭제가 된다.
그러니 실수로 카테고리를 하나만 삭제해도 대형사고가 터지게 된다.
많은 카테고리를 한꺼번에 삭제하는 이런 위험한 기능은 더더욱 있을 필요가 없다.
여기서는 일단 Category 리소스 테이블에서만 이 기능을 없앴지만, Role이나 Permission도 마찬가지로 일괄 삭제 기능이 딱히 필요 없다.
원한다면 그쪽에서도 같은 작업을 해도 괜찮을 것 같다.
filament 관리자 메뉴에서 데이터 삭제 시 비밀번호를 묻는 기능
일괄 삭제를 할 수 있는 기능을 없앤 테이블의 모습이다.
왼쪽에 있던 체크박스가 없어진 게 보인다.
그런데 여기서 보안을 좀 더 강화해 보겠다.
수정 페이지에서 데이터를 삭제하려고 할 때, 비밀번호를 입력해야 삭제되는 기능을 구현하려고 한다.
(캡처 이미지에 보이는 ㅇㅇ이라는 대충 만들어놓은 카테고리가 실험용으로 삭제하려고 만든 카테고리다.)
먼저 기능을 구현하기 전의 모습이다.
수정 페이지에서 오른쪽 상단에 있는 삭제 버튼을 클릭하면 "이 작업을 수행하시겠습니까?"라는 메시지의 모달창이 뜬다.
여기서 '삭제'를 다시 한번 클릭하면 카테고리는 그대로 삭제된다.
app/Filament/Resources/Categories/Pages/EditCategory.php
DeleteAction::make()
->action(function ($record, array $data, DeleteAction $action) {
$user = Auth::user();
if (! $user || ! Hash::check($data['password'], $user->password)) {
Notification::make()
->title('비밀번호가 일치하지 않습니다.')
->danger()
->send();
$action->cancel();
}
$record->delete();
})
->requiresConfirmation()
->modalHeading('카테고리 삭제')
->modalDescription('이 카테고리를 삭제하려면 비밀번호를 입력하세요.')
->schema([
TextInput::make('password')
->password()
->label('비밀번호 입력')
->required(),
])
기존의 DeleteAction::make()에 카테고리를 삭제하기 전에 비밀번호 입력을 요청하는 사용자 지정 작업을 추가했다.
->action(function ($record, array $data, DeleteAction $action) { ... }): 이 메서드 내부에 레코드 삭제 로직이 포함되어 있다. 첫 번째 인자($record)는 삭제 대상 모델 데이터, 두 번째 인자(array $data)는 폼 입력값 배열, 세 번째 인자(DeleteAction $action)는 현재 액션 객체 자체다.$user = Auth::user();: 현재 로그인한 사용자 정보를 가져온다.if (! $user || ! Hash::check($data['password'], $user->password)): 폼에 입력한 문자열($data['password'])과 DB에 암호화되어 저장된 현재 사용자(관리자)의 비밀번호($user->password)를 비교한다. 그리고! $user ||로 세션 만료 등의 이유로 로그인 정보가 없으면 치명적 에러가 나는 것을 방지한다.Notification::make()->...->send(): 빨간색 Danger 스타일의 토스트 메시지를 띄운다.$action->cancel();: 삭제 로직으로 넘어가지 않도록 삭제 프로세스를 중단하고, 열려있던 모달창을 닫는다.$record->delete();: 비밀번호가 일치하면 if문을 통과해서 이 라인에 도달하고, 카테고리를 실제로 삭제한다.->requiresConfirmation(): 삭제 버튼을 눌렀을 때 즉시 삭제하지 않고 확인 모달창을 띄우도록 한다.modalHeading()과 modalDescription(): Confirm 모달에 표시될 텍스트를 사용자 지정한다.->schema([ ... ]): 모달 내부 양식(Form)에 들어갈 입력 필드를 정의한다.TextInput::make('password'): 입력받은 값을$data['password']키로 저장한다.->password(): 패스워드이기 때문에 입력한 텍스트를 •••• 형태로 가려준다.->required(): 비밀번호를 입력하지 않으면 제출되지 않도록 필수 값으로 지정한다.
수정 후에는 이렇게 비밀번호를 입력하라는 메시지의 모달창이 뜨게 된다.
입력한 비밀번호가 틀리면 오른쪽 상단에 이런 토스트 메시지가 뜨게 되고, 카테고리는 삭제되지 않은 채로 모달창이 닫힌다.
정확한 비밀번호를 입력하면 '삭제 완료'라고 토스트 메시지가 뜨고, 해당 카테고리는 실제로 삭제된다.
이 기능은 관리자가 항상 맨정신으로 신중하게 웹사이트를 관리한다면 굳이 필요하지는 않은 기능이다.
하지만 이렇게 filament의 DeleteAction을 커스텀하여 비밀번호 검증 단계를 추가하면 관리자 페이지의 보안성을 한층 더 높일 수 있다.
안전한 웹 서비스 운영을 위해 중요한 리소스에는 이 기능을 꼭 적용해 보자.
다음 포스트





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