2013-05-24 8 views
5

Zrobiłem klasę uwierzytelniania po prostu tak:obiekt 'WSGIRequest' nie ma atrybutu 'successful_authenticator'

Token Authentication for RESTful API: should the token be periodically changed?

restapi/settings.py

REST_FRAMEWORK = { 
    'DEFAULT_AUTHENTICATION_CLASSES': (
     'rest_framework.authentication.BasicAuthentication', 
     'rest_framework.authentication.SessionAuthentication', 
     # 'rest_framework.authentication.TokenAuthentication', 
     'restapi.authentication.ExpiringTokenAuthentication', 
    ), 
    'PAGINATE_BY': 10 
} 

restapi/authentication.py

import datetime 
from rest_framework.authentication import TokenAuthentication 

class ExpiringTokenAuthentication(TokenAuthentication): 
    def authenticate_credentials(self, key): 
     try: 
      token = self.model.objects.get(key=key) 
     except self.model.DoesNotExist: 
      raise exceptions.AuthenticationFailed('Invalid token') 

     if not token.user.is_active: 
      raise exceptions.AuthenticationFailed('User inactive or deleted') 

     # This is required for the time comparison 
     utc_now = datetime.utcnow() 
     utc_now = utc_now.replace(tzinfo=pytz.utc) 

     if token.created < utc_now - timedelta(hours=24): 
      raise exceptions.AuthenticationFailed('Token has expired') 

     return token.user, token 

restapi/tests.py

def test_get_missions(self): 
    """ 
    Tests that /missions/ returns with no error 
    """ 
    response = self.client.get('/missions/', HTTP_AUTHORIZATION = self.auth) 

W moich testach, mam wyjątek AttributeError: 'WSGIRequest' object has no attribute 'successful_authenticator'

Dlaczego mam ten błąd? Jak to naprawić?

+0

powinno być '' nie self.request' wezwania do? – karthikr

+0

Nie jest to niezwiązane. –

+0

co masz na myśli mówiąc, że nie jest to powiązane? – karthikr

Odpowiedz

6

Problem pochodzi z linii:

utc_now = datetime.utcnow() 

co powoduje AttributeError: 'WSGIRequest' object has no attribute 'successful_authenticator'.

Minęło trochę czasu, odkąd natknąłem się na taki mylący komunikat o błędzie.

Oto jak rozwiązać go:

restapi/authentication.py

import datetime 
from django.utils.timezone import utc 
from rest_framework.authentication import TokenAuthentication 
from rest_framework import exceptions 

class ExpiringTokenAuthentication(TokenAuthentication): 
    def authenticate_credentials(self, key): 
     try: 
      token = self.model.objects.get(key=key) 
     except self.model.DoesNotExist: 
      raise exceptions.AuthenticationFailed('Invalid token') 

     if not token.user.is_active: 
      raise exceptions.AuthenticationFailed('User inactive or deleted') 

     utc_now = datetime.datetime.utcnow().replace(tzinfo=utc) 

     if token.created < utc_now - datetime.timedelta(hours=24): 
      raise exceptions.AuthenticationFailed('Token has expired') 

     return (token.user, token) 
+0

Miałem podobny problem, ponieważ próbowałem uzyskać dostęp do 'user.username' na niestandardowym modelu użytkownika –

+1

wow tak bardzo, aby wyświetlić jasne komunikaty o błędach! –

+0

Właśnie spotkałem się z tego rodzaju problemem, to jest ogólnym wyjątkiem w uwierzytelnianiu. Wygląda na to, że wyjątek zostanie zamaskowany jako udane uwierzytelnienie, ale bez ustawionych obiektów request.user i auth. – jacob