2012-04-05 15 views
11

Durante la scrittura di alcune visualizzazioni per rispondere a richieste Ajax, trovo un po 'strano che il decoratore login_required restituisca sempre un codice di stato 302 per utenti non autenticati. Dal momento che queste viste sono viste ajax, ciò sembra in qualche modo inappropriato. Non voglio che l'utente effettui il login in questo caso, ma voglio che Django dica al cliente che è richiesta l'autenticazione per accedere a tale vista (un 401 dovrebbe essere il codice di stato giusto, penso).decoratore login_required su viste ajax per restituire 401 anziché 302

Per raggiungere questo obiettivo, ho iniziato a scrivere il mio decoratore login_required_ajax, ma in qualche modo questo è al di là delle mie capacità. Questo è quello che sono venuto in mente finora:

def login_required_ajax(function=None,redirect_field_name=None): 
    """ 
    Just make sure the user is authenticated to access a certain ajax view 

    Otherwise return a HttpResponse 401 - authentication required 
    instead of the 302 redirect of the original Django decorator 
    """ 
    def _decorator(view_func): 
     def _wrapped_view(request, *args, **kwargs): 
      if request.user.is_authenticated(): 
       return view_func(request, *args, **kwargs) 
      else: 
       return HttpResponse(status=401) 

     if function is None: 
      return _decorator 
     else: 
      return _decorator(function) 

Quando si utilizza questa decoratore su una visione, io ottenere un'eccezione ViewDoesNotExist non appena provo ad accedere a qualsiasi pagina del sito.

Prima ho pensato che il problema potesse essere il ritorno diretto di un HttpResponse quando un utente non è autenticato, perché un oggetto risposta non è un chiamabile. Ma poi il decoratore dovrebbe funzionare fintanto che non cerco di accedere alla vista in questione, non dovrebbe? E se questo è davvero il punto cruciale, come posso scrivere un decoratore che restituisce un HttpResponse con un codice di stato di 401?

+1

Un'idea che non si tratta di tuo regista: Si potrebbe anche introdurre un middleware, che controlla se una richiesta è una richiesta AJAX e restituisce un '401 'se rileva che la vista restituisce un' 302' per l'accesso ... Quindi potresti continuare ad usare il decoratore di Django e gestire le richieste normali e normali ajax ... –

+3

Ti sembra davvero più semplice di: "Crea un decoratore personalizzato e usarlo su viste ajax "? ;) – marue

risposta

14

Questo è un buon tentativo. Ecco un paio di problemi che ho notato:

  1. La funzione _decorator deve restituire _wrapped_view.
  2. L'indentazione per il blocco if function is None è un po 'off - la funzione login_required_ajax deve restituire la funzione decorata.

Ecco il decoratore con tali modifiche fatte:

def login_required_ajax(function=None,redirect_field_name=None): 
    """ 
    Just make sure the user is authenticated to access a certain ajax view 

    Otherwise return a HttpResponse 401 - authentication required 
    instead of the 302 redirect of the original Django decorator 
    """ 
    def _decorator(view_func): 
     def _wrapped_view(request, *args, **kwargs): 
      if request.user.is_authenticated(): 
       return view_func(request, *args, **kwargs) 
      else: 
       return HttpResponse(status=401) 
     return _wrapped_view 

    if function is None: 
     return _decorator 
    else: 
     return _decorator(function) 
+0

Funziona come un fascino. Grazie. – marue

Problemi correlati