새로운 권한설계 고민 #77
Dong-Hyeon-Yu
started this conversation in
백엔드
Replies: 1 comment
-
예전에 올린 내용 같은데 지금 읽어보니 인상 깊네. |
Beta Was this translation helpful? Give feedback.
0 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
-
— 기존 권한 검사 문제점 —
유저마다 역할과 그룹이 있는데,
어떤 url 요청이 있을 때마다 해당 유저의 역할과 그룹을 확인하는 함수를 이용했다.
권한 관련 설정이 초기에 계획했던 것보다 더 복잡해지면서,
if 문으로 추가되는 코드량이 점점 많아졌다.
현재는 유저 역할이나 그룹에 대한 변경이 필요할 시에,
거의 변경 불가능한 코드가 되어버렸다.
아래 아주 간단한 코드 예시..
![제목 없음](https://user-images.githubusercontent.com/81698076/139589734-546a3e5a-4b46-4e81-9f51-7b11963c318c.png)
— 생각한 대안 —
— 구현 방법 —
1. 기존 User 모델을 장고에서 제공하는 기본 User 모델(auth_user)과 연동
— 연동하기로 결정한 이유 —
원래는 테이블을 새로 다 설계한 후, 서비스별 권한을 세분화하여 테이블을 작성해야한다. 그런데 django-auth 에서 앱을 생성할 때마다 auth_permission 이라는 테이블에 해당 권한을 자동으로 추가해놨던 것을 발견했다.
처음 이 서비스를 개발했던 선배님께서는 django 에서 제공하는 기본 User model 를 사용하지 않고, 개별적인 User model 을 생성해서 사용했다. 중간부터 개발에 참여했어서 아무생각 없이 user 모델을 사용했었는데, 장고에서 제공하는 user모델을 사용하게 되면 user 모델과 연동해서 제공하는 기능들이 꽤 있었다. 더 알아보니 권한 관련 기능도 제공하고 있었다. auth_permission 테이블의 정체가 그 기능을 위한 것 중 하나였다.
현재 프론트엔드에서는 vue.js 를 도입하는 중에 있어서 본격적인 개발이 진행되기 전에 권한 관련 문제를 해결해야했다. 새로 바닥부터 설계하고 구현하려면 너무 많은 시간이 들어가니 장고 퍼미션 기능을 사용하기로 했다. 장고 퍼미션을 사용하려면 먼저 기존의 User 모델을 장고의 User 모델과 연동시켜야만 한다. 주의해야할 점은 기존에 배포하던 서비스에 문제가 생기지 않도록 해야 한다는 것. 기존 db 테이블 컬럼이나 레거시 코드를 직접적으로 수정하면 안되고, 새로운 코드를 추가하여 테스트 후에 점진적으로 교체해야함.
— 구현 —
연동 전략을 고민하는 데 있어서 중요하게 고민했던 지점은 3가지이다.
1. 사용중인 User 모델이 AbstractBaseUser 상속
2. 장고 유저 모델(auth_user) & 현재 사용중인 유저 모델(user_profile) 1대 1 매핑
위의 내용을 토대로 판단하여, 두번째 방법을 선택했다.
2. 커스텀 backend.py 구현
— 배경 —
장고의 권한 검사는 django.contrib.auth 에서 담당한다. 여러 기능들이 있지만 결국 최종적인 권한 검사는 ModelBackend 클래스에서 담당한다. 유저 또는 유저그룹에서 접근 가능한 서비스 목록에, 인자로 넘겨받은 서비스 이름이 존재하면 통과한다. 접근 가능한 서비스 목록을 검사하는 중에 캐쉬되어 있는지 먼저 확인하고, 없으면 db를 확인한다. db 확인 후에는 캐싱 후에 반환한다. _get_permissions 라는 함수가 그런 역할을 한다.
캐시하는 방식이 인상 깊었는데, user._user_perm_cache = ['board_view', 'board_create', ] 이렇게 단순히 메모리에 저장하는 방식으로 구현하고 있었다. 동아리 홈페이지 같이 동시접속자가 매우 낮은 환경에서는 간단하고 매우 좋은 방법이다!! 이 방식은 힙 메모리에 캐싱하는 방식! 다른 캐시 db 들은 어떤 식으로 캐싱하는 지 궁금해졌다.
어쨌든 django.contrib.auth.models 에 정의된 테이블을 기반으로 ModelBackend 가 권한 검사를 수행한다는 것을 파악했다. 하지만 우리는 user group 말고도 user role 이 따로 존재한다. auth.models 에는 user&group&permission 간 m2m 필드를 설정되어 있다. role 검사를 추가적으로 하기 위해서는 user&role&auth.models.permission 간 m2m 필드를 설정하고, ModelBackend 에서 role 권한 검사 로직을 추가해줘야 한다.
— 구현 —
진행사항 (2021-11-14 #89)
custom backend.py
를 지웠음. (실제로 구현까지 하고 작동 확인했었다... 맴찢...)Beta Was this translation helpful? Give feedback.
All reactions