주문 취소 기능을 고치고 확인하려는데 화면에 btnCancel 이 안 보였다. 내 계정에 그 권한이 없었기 때문이다.
Table of contents
Open Table of contents
안 보이니 확인을 못 한다
views/ 의 화면 코드가 auth->has 로 권한을 보고 없으면 버튼을 아예 안 그리고 있었다.
<?php if ($this->auth->has('order.cancel')): ?>
<button id="btnCancel">주문 취소</button>
<?php endif; ?>
btnCancel 을 눌러 볼 수가 없으니 고친 것이 도는지 확인할 방법이 없다. 방법이 셋 있었다.
권한을 가진 계정으로 들어가거나 내 계정에 권한을 주거나 주소를 직접 치는 것이다. 두 번째는 시험 뒤에 DELETE 로 되돌리는 것을 잊기 쉽다. 세 번째는 POST 를 직접 만들게 되니 화면 흐름이 빠져 확인이 반쪽이 된다.
권한별 시험 계정을 만들었다
역할별로 계정을 만들어 두고 필요한 것으로 들어가게 했다. 시험 자료에 넣어 뒀다. ENVIRONMENT 가 운영이면 안 딸려 간다.
test_admin 전체 권한
test_manager 주문 관리 권한
test_cs 조회만
test_none 권한 없음
계정을 만들고 나니 확인해 볼 것이 하나 더 생겼다. test_none 으로 주소를 직접 쳐 봤더니 그대로 처리가 됐다.
화면에서 가리는 것은 보안이 아니다
auth->has 가 화면에만 있고 cancel 메서드에는 없었다. 화면에서 버튼만 안 보였을 뿐 서버는 아무것도 막지 않고 있었다.
public function cancel($orderNo)
{
if (!$this->auth->has(PERM_ORDER_CANCEL)) {
show_error('권한이 없습니다', 403);
return;
}
...
}
같은 조건이 화면과 처리 두 곳에 생기므로 PERM_ORDER_CANCEL 상수로 뺐다. 두 곳에 적힌 문자열이 어긋나면 같은 문제가 다시 난다.
응답을 403 으로 준 데는 이유가 있다. 자기가 볼 수 있는 주문인데 그 동작만 못 하는 경우여서다. 남의 것을 못 보게 하는 자리는 다르다. 거기는 존재 여부가 새지 않게 show_404 로 통일했다.
같은 상태인 자리가 더 있는지 grep -rc 로 세어 봤다. views/ 에 조건이 34개인데 controllers/ 에는 11개였다. 화면 34개를 하나씩 보고 대응하는 처리를 봤다. 확인이 없는 것이 19개였고 전부 넣었다.
시험 항목에도 권한 조합을 넣었다. test_manager 로 눌러서 되는지를 본다. test_cs 에 버튼이 안 보이는지를 본다. test_none 으로 주소를 직접 쳤을 때 403 이 오는지도 본다. 세 번째가 이번에 추가된 항목이다.
같은 구조를 가진 것들
권한 말고도 같은 모양을 가진 자리가 있었다. status 가 cancel 인 주문에는 취소 버튼이 안 나오는데 주소를 직접 치면 다시 취소됐다.
if ($order->status == 'cancel') {
return error('이미 취소된 주문입니다');
}
기간이 지난 이벤트 응모도 마찬가지였다. 버튼은 end_date 가 지나면 사라지는데 처리는 그대로 열려 있었다. 화면에서 가리는 조건이 있으면 처리에도 같은 조건이 있어야 한다는 것이 권한만의 이야기가 아니었다.
정리
- 조건으로 가려지는 화면은 그 조건을 만들어야 확인이 된다
- 역할별 시험 계정을 만들어 두면 조건을 쉽게 만든다
- 화면에서 가리는 것은 보안이 아니다. 주소를 직접 치면 처리된다
auth->has를 화면과 처리 양쪽에 두고PERM_ORDER_CANCEL상수로 뺀다- 동작만 못 하는 자리는
403, 남의 것은show_404로 나눈다 grep -rc로views/와controllers/의 조건 개수를 세면 빠진 곳이 드러난다- 시험 항목에
test_none으로 주소를 직접 치는 것을 넣는다 status나end_date로 가리는 것들도 같은 구조다