2009-10-10 2 views
25

다른 사람들이 어떻게 설계할지에 대한 의견을 찾고 있습니다. 나는 클래스 (django 그룹) 기반 뷰를 제공 할 것이다.장고 역할 기반보기?

예를 들어 사용자 그룹은 액세스 권한이있는보기/템플릿을 결정합니다. 사용자의 링크 표시 줄이 무엇을 구성할지 결정하기 위해 표에 함수를보기 위해 경로를 저장하는 방법을 생각 중입니다. 필터 스펙은이 템플리트를 채울 행을 판별하기 위해 저장할 수도 있습니다.

좋은 예가 병원 간호 단위입니다. 한 단위의 간호사는 전체 병원의 환자를 볼 필요가 없습니다. 그들은 환자를 볼 필요가 있습니다. 같은 부서의 의사들도 환자를 만 볼 필요가 있지만 더 많은 기능을 이용할 수 있어야합니다.

일부 타사 응용 프로그램을 통해이 작업을 수행 했습니까? 그리고 어떻게이 문제에 접근하겠습니까?

덕분에, 피트

+1

얘들 아, 장고 허가 시스템은 내 요구에 맞게하지 않습니다. 이것이 아키텍처 도움말을 요청하는 이유입니다 : P – slypete

답변

38

장고는 이미 목적을 위해 충분한 될 수있는 그룹 및 권한 시스템을 가지고 있습니다. 사용자가 권한이 있는지

http://docs.djangoproject.com/en/dev/topics/auth/

일반적으로 코드에서 당신은 확인합니다. 사용자는 자신의 권한과 자신이 속한 그룹의 권한을가집니다. 관리 콘솔에서 쉽게 관리 할 수 ​​있습니다.

살펴볼 부분이 두 부분 있습니다.

  1. 페이지를 요청하는 사용자에게 권한이 있는지 확인하십시오.
  2. 에게 권한이있는 경우에만 사용자에게 링크를 표시하십시오.

1. 위해 당신은 같은 장식의 권한을 확인할 수 있습니다 2.를 들어 현재 로그인 한 사용자의 권한이 템플릿 변수 {{파마}}에 저장됩니다

from django.contrib.auth.decorators import permission_required 

@permission_required('polls.can_vote') 
def some_view(request): 

. 이 코드는 위와 동일한 권한을 검사합니다.

{% if perms.polls.can_vote %} 
    <a href="/vote">vote</a> 
{% endif %} 

는 user.get_all_permissions (반복 수있는 링크 목록)을 생성하고 링크를 가져 오기 (또는 링크 생성 기능)을 딕셔너리에서하려면 다른 아마 많은 사람들이있다

def more_elaborate_list_of_links_for_a_perm(user): 
    return ["/link1", ...] 

_LINKS = { 
    'polls.can_vote' : lambda u: ["/user/specific/link/" + u.id], 
    'polls.can_close': lambda u: ['/static/link/1', 'static/link/2'], 
    'polls.can_open' : more_elaborate_list_of_links_for_a_perm 
} 

def gen_links(user): 
    # get_all_permissions also gets permissions for users groups 
    perms = user.get_all_permissions() 
    return sum((_LINKS[p](user) for p in perms if p in _LINKS), []) 

을 구혼.

+1

django의 기본 제공 권한 시스템을 사용하여 사용자에게 제공하는 링크 목록을 어떻게 생성합니까? – slypete

+1

기록을 위해 나는이 대답을 최고로 선택하지 않았다. 나는 그것이라고 생각하지 않는다. – slypete

1

실제 개체 별 ACL이 필요없는 경우 Django 사용 권한 시스템 만 사용할 수 있습니다.

from django.contrib.auth.models import Permission 
perms = Permission.objects.all() 

API for other authentication and authorization sources있다, 그래서 당신이 권한 테이블을 고수 할 필요가 없습니다 : 사용 가능한 모든 권한 목록을 얻으려면.

이 장고 시스템을이 인증 모델 (RBAC)과 관련하여 사용자의 필요에 맞게 해킹하거나 ACL과 같은 해결책을 제시 할 수 있습니다.

+0

개체 당 acl에 대한 힌트가 있습니까? – gpilotino

4

우리는 비슷한 문제가있었습니다. Django의 그룹은 이것에 정말로 적합하지는 않지만, 여러분은 그들을 구속 할 수 있습니다.

우리는 다음과 같이 그것이했던 방법 :

모든 액세스 제어 개체가 그룹 테이블에 ManyToMany 관계를 가지고있다. 각 그룹은 특정 유형의 권한을 정의하는 데 사용되었습니다 ("환자 기본 사항을 볼 수 있음", "환자 연락처 정보를 편집 할 수 있음"등). 사용자는 권한이 있어야하는 그룹에 추가됩니다 (이 병원의 환자 만 보는 예로는 "계곡 전망 병원"그룹이있을 수 있습니다).

그런 다음 레코드 목록을 사용자에게 표시하려면 두 그룹의 결합을 기준으로 필터링합니다. 사용자는 주어진 개체를 볼 수있는 모든 관련 그룹 권한이 있어야합니다.

시스템에서 필요로하는 경우 음수 권한의 별도 ManyToMany를 유지하거나 읽기/쓰기 권한을 별도로 유지할 수 있습니다. 또한 조회 권한 필터를 사용하여 실제 사용 권한 집합을 검색하는 일련의 메타 그룹 (의사, 간호사)을 정의 할 수 있습니다.

링크 모음 문제가 생기면 사용자가 보거나 편집 할 수있는 개체 클래스를 기반으로하는 필터를 get_absolute_url() 형식의 함수 (어쩌면 get_index_url()이라고 부름)를 사용하여 프로그래밍 방식으로 생성 할 수 있습니다.)를 사용하여 객체의 각 클래스 색인에 대한 링크를 반환합니다.

이 모든 것이 상당히 복잡하기 때문에 이러한 사항에 대해 일정 수준의 캐싱을 원하지만 결국 최적화를 방해하기 전에 작동 시키십시오. 그것은 가능하고, 말로 표현하는 것보다 코드에서 덜 추합니다.

+0

나는이 길을 우리 앱으로 끝내었지만 그 이상은 아니었다. 성능이 조금 떨어졌습니다. 나는 더 나은 ACL 솔루션을 찾기 위해 다른 곳을 찾고있다 – Gevious

+0

이것은 확장 성이 전혀 없다. ACL에 대한 아이디어가 있습니까? – user710907

2

나는 비슷한 문제를 너무 오래 전에 가지고있었습니다. 우리의 솔루션은 당신의 상황에 너무 단순 할 수도 있지만 트릭을했습니다. 모든 사람들이 제안하는 것처럼 Django 권한 시스템을 사용하여 모델과 사용자 상호 작용을 제어했습니다. 그러나 사용자를 그룹화하지 않고 GenericForeignKey를 통해 개체를 그룹화했습니다.

우리는 계층 구조를 개발할 수 있도록 자체에 연결된 모델을 만들었습니다.

class Group(models.Model): 
    name = models.CharField(...) 
    parent = models.ForeignKey('self', blank=True, null=True) 
    content_type = models.ForeignKey(ContentType) 
    object_id = models.PositiveIntegerField() 
    content_object = generic.GenericForeignKey('content_type', 'object_id') 
    ... 

우리는 django 사용자 모델의 사용자 프로필로 사용할 모델을 만들었습니다. 포함 된 모든 것은 위의 그룹 모델에 연결된 ManyToManyField입니다. 이를 통해 사용자는 필요에 따라 0 개 이상의 그룹에 대한 액세스 권한을 부여 할 수있었습니다.

class UserProfile(models.Model): 
    user = models.ForeignKey(User, unique=True) 
    groups = models.ManyToManyField(Group) 
    ... 

이 (documentation)

은 우리에게 두 세계의 최고를주고 장고의 허가 시스템에 모든 것을 구둣 주걱 노력에서 우리를 유지했다. 이 기본 설정을 사용하여 스포츠 콘텐츠에 대한 사용자의 액세스를 제어합니다 (일부 사용자는 전체 리그에 액세스 할 수 있고 일부 회의는 하나 또는 두 회의, 일부는 개별 팀에만 액세스 할 수 있음). 아마 당신의 필요에 맞게 일반화 될 수 있습니다.

1

Pinot Noir 와인 전문가는 다양한 기준에 따라 개체 단위 액세스를 만들었습니다. 인바운드 링크에 추천 된 와이너리의 도메인 이름과 일치하는 리퍼러 필드가있는 경우 해당 와이너리와 관련된 모든 기사, 시음 노트 등으로 확장 된 '와이너리 토큰'이 사용자에게 있습니다. 우리는 시음 행사를 위해 '명명 된 토큰'을 사용하고 사이트의 특정 부분에 대한 액세스 권한을 부여했습니다. Google은 검색 엔진 스파이더에 특정 유형의 권한을 부여한 다음 이러한 검색 엔진에서 가져온 링크가 거미와 동일한 권한 (즉, 클로킹 게임 없음)을 가지는지 확인하기 위해이 방법을 사용합니다.

짧은 버전은 클래스를 만들 수 있습니다 (토큰을 보유하고있는 TokenBuckets이라고 함). 특정 레벨의 (사용자가) 특정 레벨을 가진 경우 사용자의 TokenBucket에 요청할 수있는 각 개체 (세부 정보 페이지 또는 목록 페이지 등) 액세스가 허용됩니다.

기본적으로 이상한 종류의 ACL 시스템입니다. 기계공을 만드는 것이 그리 어렵지 않았습니다. 모든 마술은 어느 환경에서 토큰이 양동이에 들어가는지를 결정합니다.

0

비슷한 문제에 대해 역할 기반 시스템을 사용했습니다. 기본적으로 사용자는 다른 역할을 맡을 수있는 권한이 있습니다.

보기 기능은 장식있어 : 마법의

def needs_capability(capability,redirect_to="/cms/"): 
    def view_func_wrapper(view_func): 
     def wrapped_view_func(request,*args,**kwargs): 
      if not request.role._can(capability): 
       return HttpResponseRedirect(redirect_to) 
      return view_func(request,*args,**kwargs) 
     return wrapped_view_func 
    return view_func_wrapper 

나머지는 상황에 맞는 프로세서 내부 세트를받은 request.role 속성 안에 있습니다. 인증 된 사용자는 닦지 않은 질량에 대해 역할이 있습니다. DummyRole. 정보

액세스는 템플릿 내에서 더 제한되었다 : 예상대로

{% if not request.role.can.view_all_products %} 
      Lots of products, yeah! 
{% endif %} 

은 깨끗한 내 의견 솔루션,하지만 일을하지 않습니다.

1

이이 질문 2009년 10월에 요청하고 문제가 계속 2012년 7월에 존재하고있다가.

나는 역할 기반 응용 프로그램을 검색했으며 최상의 결과로 django-permission을 찾았습니다. 내가 필요

세 가지 중요한 기능은 역할,보기 장식Templatetag했다; 외관상으로는 django-permissions에는 전부가있다. 사용법은 docs입니다.

유일한 단점은 개발 중이라는 것입니다.