2013-05-24 4 views
5

J'ai fait une classe d'authentification comme ça:objet 'WSGIRequest' n'a pas d'attribut '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) 

Dans mes tests, j'ai une exception AttributeError: 'WSGIRequest' object has no attribute 'successful_authenticator'

Pourquoi ai-je cette erreur? Comment le réparer?

+0

devrait 'self.request' pas' request.'? – karthikr

+0

Non, ce n'est pas lié. –

+0

que voulez-vous dire, il n'est pas lié? – karthikr

Répondre

6

Le problème vient de la ligne:

utc_now = datetime.utcnow() 

qui provoque AttributeError: 'WSGIRequest' object has no attribute 'successful_authenticator'.

Cela fait un moment que je suis tombé sur un tel message d'erreur trompeuse.

Voici comment je l'ai résolu:

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

J'ai eu un problème similaire causé essayant d'accéder 'user.username' sur un modèle d'utilisateur personnalisé –

+1

wow tant pour effacer les messages d'erreur! –

+0

Je viens de rencontrer ce genre de problème, c'est-à-dire une exception générale dans l'authentification. Il semble que l'exception soit masquée en tant qu'authentification réussie, mais sans que les objets request.user et auth soient définis. – jacob

Questions connexes