2013-05-24 12 views
5

Ho fatto una classe di autenticazione proprio così:oggetto 'WSGIRequest' non ha alcun attributo '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) 

Nel mio test, ho un'eccezione AttributeError: 'WSGIRequest' object has no attribute 'successful_authenticator'

Perché ho questo errore? Come sistemarlo?

+0

dovrebbe 'self.request' non essere' request.'? – karthikr

+0

No, non è correlato. –

+0

cosa vuoi dire che non è correlato? – karthikr

risposta

6

Il problema deriva dalla linea:

utc_now = datetime.utcnow() 

che provoca AttributeError: 'WSGIRequest' object has no attribute 'successful_authenticator'.

È passato un po 'di tempo da quando mi sono imbattuto in un messaggio di errore così fuorviante.

Ecco come ho risolto:

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

Ho avuto un problema simile causato provando ad accedere a 'user.username' su un modello utente personalizzato –

+1

wow così tanto per cancellare i messaggi di errore! –

+0

Ho appena riscontrato questo tipo di problema, ovvero un'eccezione generale nell'autenticazione. Sembra che l'eccezione venga mascherata come autenticazione riuscita, ma senza request.user e auth objects set. – jacob