django drf를 쓰다 보면, IsAuthenticatedOrReadOnly와 IsAuthenticated를 많이 보게 됩니다. 아주 많이 쓸 텐데요. 사용 용례를 통해서 차이점을 알아보도록 하겠습니다.

 


 먼저 permissions.py를 보시면, SAFE_METHODS가 정의되어 있어요. 'GET', 'HEAD', 'OPTINS' 라고 정의되어 있습니다. 특히 get은 read-only request로 잘 알려진 메서드입니다.

 

 

 IsAuthenticatedOrReadOnly는 request.method가 get, options, head 이거나, 혹은 유저가 인증 되어 있는 상태이면 참을 리턴합니다. 즉, 익명의 유저에 대해서는 get, options, head만 허용합니다.

 

 다음에 IsAuthenticated입니다. 이것은, user가 인증이 된 경우에만 True를 리턴합니다. 이 과정을 view를 타기 전에 실행하게 됩니다. view level check라고 이해하면 편하겠네요.

 


 이 둘을 언제 쓸까요?

 

 

 posts api의 경우, 인증이 되지 않은 상태에서도 마음대로 볼 수 있어요.  그런데, 로그인을 한 유저만 post를 쓸 수 있어요. 이런 경우에, get과 같이 read only method 말고는 인증이 된 경우에만 허용을 해야 겠네요. 게시물 수정이나 삭제의 경우 자기 자신이 쓴 글만 허용해야 하는데, object 레벨에서 permission을 주면 됩니다. 혹은 view 안의 메서드 내에서 직접 권한을 검사하는 방법도 있습니다. 반면에, 이런 경우는 어떨까요? 내 계정에 대한 정보를 본다.

 

 

 이 경우, 익명 유저가 접근하는 것을 막아야 합니다. 내 계정에 대한 정보를 보는데, 익명 유저에 대한 정보는 알 길이 없기 때문입니다. 이럴 때에는, permission_classes를 IsAuthenticated로 설정하면 됩니다. 계정 정보를 보는데, 당연히 인증이 되어야 겠지요.

 

 

 예를 들어, 이 경우는 어떨까요? Me라는 APIView는, /api/v1/account/로 걸려있습니다. 이 경우, 인증이 되어 있어야 get 메서드를 탈 수 있어요. 그렇지 않으면, permission을 체크하는 과정에서 거부당할 겁니다.

 

 

 로그인이 안 된 경우, MeView 레벨에서 권한 체크를 하는 과정에서 거부당했습니다.

 

 

 UserView는 /api/v1/account/<str:username>/으로 걸려 있어요. 이 APIView에는 get과 post가 있는 모양이군요. 이 상태에서 get과 post를 걸어봅시다.

 

 

 인증이 안 된 상태에서 get 요청을 보내니, 잘 됨을 확인할 수 있어요.

 

 그런데, post는 403이 떨어집니다. post가 Read-only 속성을 가지는 method가 아니기 때문입니다. IsAuthenticated와 

IsAuthenticatedOrReadOnly의 차이가 확실하게 이해가 되셨을 듯 싶습니다.