2013-10-16 3 views
0

Django-Tastypie에서 사용자 정의 인증을 사용하고 있는데 인증이 성공하면 사용자 이름과 비밀번호를 반환합니다. 그 이름과 해당 암호는 메타 클래스에서 사용할 수 없기 때문에,Tastypie에서 Django 모델로 사용자 자격 증명 전달

class TestResource(ModelResource): 

    class Meta: 
     queryset = Test.remote_supported.get_all(username,password) 
     resource_name = 'test' 
     filtering = { 
      'id' : ALL, 
     } 
     detail_allowed_methods = ['get', 'post', 'patch']  
     authorization = Authorization() 
     authentication = MyCustomAuth() 
     always_return_data = True 

    def __init__(self, api_name=None): 
     self.username = None 
     self.password = None 
     super(TestResource, self).__init__(api_name) 

    def is_authenticated(self, request): 
     auth_result = self._meta.authentication.is_authenticated(request) 

     if isinstance(auth_result, HttpResponse): 
      raise ImmediateHttpResponse(response=auth_result) 

     if not auth_result is True: 
      raise ImmediateHttpResponse(response=http.HttpUnauthorized()) 

     # this is where I receive the username and password from my custom auth 
     self.username, self.password = self._meta.authentication.get_credentials() 

이 코드는 분명히 작동하지 않습니다, 그것은하더라도 : 인증이 성공되면 ModelResource 인스턴스에서, 사용자 이름과 암호를 사용할 수 있습니다 그것을 변경하는 것은이 인스턴스에만 영향을 미치지 않을 것이지만, 모든 인스턴스 (사용자의 의도가 아닌)는 사용자 이름과 비밀번호의 범위가 RESTful 쿼리마다 있어야하기 때문입니다.

이 내 모델이 모습입니다 :

class RemoteAuthSupported(models.Manager): 
    def get_all(self, username, password): 
     # ... here I do some custom operations with the username and password 
     return super(RemoteAuthSupported, self).get_query_set() 

class Test(models.Model): 
    objects = models.Manager() 
    remote_supported = RemoteAuthSupported() 

    # ... the field declarations follow here ... # 

나는 이것이 내가 자신의 인증을 필요로 내 장고 응용 프로그램과 비 ORM 데이터 소스를 사용하고 있다는 것입니다 수행하려고하는 이유, 동일한 사용자 이름과 비밀번호로 Tastypie ModelResource에서 Django Model로 전달하는이 매개 변수를 처리하는 방법은 무엇입니까? 아마도 여기에 사용중인 사용자 모델이 없다는 것을 언급해야합니다.

답변

1

요청에 대한 리소스 목록을 반환하는 obj_get_list 메서드를 재정의 할 수 있습니다. 또한 사용자 이름과 암호를 request 개체 자체로 설정할 수 있으므로 매개 변수가 요청 - 응답 경로를 통해 전달됩니다. 또한 querysetall()으로 설정해야합니다.

def obj_get_list(self, bundle, **kwargs): 
    original = super(TestResource, self).obj_get_list(bundle, **kwargs) 
    request = bundle.request 
    return original.get_all(request.username, request.password) 

다른 방법으로는 개체 목록을 필터링 할 사용자 지정 권한을 추가 할 수 있습니다. request 속성 부분이 여전히 보유됩니다. 오히려 단지 교류리스트 엔드 포인트보다 get_all를 사용하여 queryset을 모방 할 경우

class MyAuth(Authorization): 
    def authorized_read_list(self, objects, bundle): 
     request = bundle.request 
     return objects.get_all(request.username, request.password) 

, 당신은 get_object_list를 오버라이드 (override) 할 수있다.

def get_object_list(self, request): 
    original = super(TestResource, self).get_object_list(request) 
    return original.get_all(request.username, request.password) 
+0

왜 'all()'을 사용해야합니까? [이 예] (https://groups.google.com/d/msg/django-tastypie/GxEVe0UTGgA/8Yyi2PmNknQJ)에 따르면 필수적인 것은 아닙니다. –

+1

필수는 아니지만 tastypie는 'queryset' 속성에서 모델 클래스를 비롯한 일부 데이터를 유추합니다. 당신이 당신의 쿼리 세트에'get_all' 메소드를 추가한다면 당신은 언제나 ModelManager를 필요로하지 않고 모든 쿼리 세트를 필터링 할 수 있습니다. ModelManager에 따라 백업 된 커스텀 쿼리 세트 메소드는 실제로 삶을 더 쉽게 만듭니다. –

0

은 내가 Tastypie 문서로보고, 그리고 아마추어이기는하지만 해결책이 될 수는 다음과 같이 보인다 : 한 번만

class TestResource(ModelResource): 

    class Meta: 
     queryset = Test.remote_supported.get_all('dummyusername','dummypassword') 
     resource_name = 'test' 
     filtering = { 
      'id' : ALL, 
     } 
     detail_allowed_methods = ['get', 'post', 'patch']  
     authorization = Authorization() 
     authentication = MyCustomAuth() 
     always_return_data = True 

    def get_object_list(self, request): 
     """ 
     This method calls a clone of the queryset declared in the Metaclass. 
     It is called every time a query is executed. 
     Here the actual username and password is passed to the model. 
     """   
     return Site.remote_supported.get_all(self.username,self.password) 

이 문제는의 검색어 선언이 메타 클래스에서 일어난 것을하지 질의 당, HTTP 요청에서 획득 한 사용자 이름과 암호는 메타 수준의 쿼리로 전달 될 수 없습니다. 그러나 get_object_list()은 선언을 복제하고 업데이트 인수 값을 사용하여 실제 호출을 수행하므로 작업이 완료됩니다. 그것은 나를 위해 일하고 있지만,이 일을 더 나은 해결책이 있어야한다고 생각합니다.