autenticação Django e Ajax - URLs que exigem login

votos
47

Eu quero adicionar um pouco de Ajax -niceness para o meu site Django-codificada.

No meu código Django, eu uso o @login_requireddecorador django.contrib.auth.decoratorsda marca que vista requer autenticação. O comportamento padrão quando um usuário não autenticado clica nele é redirecionar o / a página de login, e em seguida, passar a página de destino.

O que eu vi em alguns sites, e realmente gostei, é que quando o usuário clica em um link que leva a um lugar restrito a usuários somente registrados, em vez de ficar redirecionado para uma página de login, ele / ela recebe uma janela pop-up (via JavaScript) pedindo ele / ela fazer login ou registre-se. Não há nenhuma parte de redirecionamento, então não há necessidade para um usuário para usar a tecla voltar se ele / ela decide que ele / ela realmente não gosta do site suficiente para desperdiçar o tempo registrar.

Assim, o qestion é: como é que você gerenciar a tarefa de marcação automaticamente alguns links como restritas para JavaScript pode lidar com seu onclickcaso e apresentar uma faça login pop-up?

Publicado 23/11/2008 em 21:35
fonte usuário
Em outras línguas...                            


5 respostas

votos
53

Estou enfrentando o mesmo problema, e, como você, eu gostaria de um decorador simples de envolver em torno de uma visão ajax Django, a fim de lidar com a autenticação da mesma forma que eu tenho outros pontos de vista. Uma abordagem que parece promissor para mim é usar tal decorador em conjunto com JavaScript que procura por um determinado valor na resposta.

Aqui é primeiro projecto de revisão do decorador:

from functools import wraps

def ajax_login_required(view_func):
    @wraps(view_func)
    def wrapper(request, *args, **kwargs):
        if request.user.is_authenticated():
            return view_func(request, *args, **kwargs)
        json = simplejson.dumps({ 'not_authenticated': True })
        return HttpResponse(json, mimetype='application/json')
    return wrapper

Aqui está o ponto de vista:

@ajax_login_required
def ajax_update_module(request, module_slug, action):
    # Etc ...
    return HttpResponse(json, mimetype='application/json')

E aqui está o JavaScript (jQuery):

$.post('/restricted-url/', data, function(json) {
    if (json.not_authenticated) {
        alert('Not authorized.');  // Or something in a message DIV
        return;
    }
    // Etc ...
});

EDIT : Eu tenho tentado usar functools.wraps, como sugerido. Eu realmente não tenho usado este decorador no código de trabalho, por isso cuidado com possíveis bugs.

Respondeu 07/02/2009 em 06:20
fonte usuário

votos
5

Concordo com S.Lott

Faça uma verificação no modelo, se o usuário está conectado, basta colocar o link como de costume, se não, colocar algo como

<a href="`link`" onclick="return login_popup()"> 

onde login_popup iria retornar false se o usuário diz cancelar.

Isso poderia ser provavelmente ser feito muito mais fácil em Jinja2 através de suas macros .

Se o modelo não sabe qual urls exigem que o usuário de login, você provavelmente precisa re-considerar o seu design.

Se você deve, eu acho que você pode fazer a mesma coisa que o despachante Django url faz para descobrir a função de visualização.
Vejo:django.core.urlresolvers

uma vez que você pegou a função de visualização você pode verificar se ele está decorado com @login_required.

Isso seria feito em uma marca personalizada, provavelmente.
Se você usar Jinja2, você não vai precisar do tag, basta implementar a função e expô-la ao Meio Ambiente, que é simples, mas você vai ter que fazer um pouco de leitura sobre a API de Jinja2)

Respondeu 24/11/2008 em 00:02
fonte usuário

votos
5

Soa como uma possibilidade modelo de página.

  1. Você poderia passar por um LINK_VIA(ou algo assim) que você fornecer como onClick="return popup(this, 'arg')"ou None. Cada link seria <A HREF="link" `LINK_VIA`>some text</a>.

    • Para sessões anônimas, LINK_VIAtem um valor.
    • Para logado sessões, LINK_VIAé None
  2. Você poderia usar uma {% if %}declaração em torno de suas <A HREF=...>tags. Isto parece prolixo.

  3. Você pode escrever sua própria marca personalizada por {% link_via %}. Eu não estou bastante familiarizado com isso, mas você pode fornecer o link e texto como cordas e sua marca pode gerar um dos dois tipos de links.

Respondeu 23/11/2008 em 22:53
fonte usuário

votos
1

Aqui é proposto versão do decorador com filme .__ doc__, enrole .__ name__

from functools import wraps

def ajax_login_required(function):
    def wrap(request, *args, **kwargs):
        if request.user.is_authenticated():
            return function(request, *args, **kwargs)
        json = simplejson.dumps({ 'not_authenticated': True })
        return HttpResponse(json, mimetype='application/json')  
    wrap.__doc__ = function.__doc__
    wrap.__name__ = function.__name__
    return wrap
Respondeu 21/08/2016 em 10:44
fonte usuário

votos
0

Construído fora de Eric Walker solução, mas para Django 2.0

# Standard Imports
import functools
import django.http

def ajax_login_required(view_func):
    @functools.wraps(view_func)
    def wrapper(request, *args, **kwargs):
        if request.user.is_authenticated:
            return view_func(request, *args, **kwargs)

        return django.http.JsonResponse('Unauthorized', status=401, safe=False)

    return wrapper
Respondeu 01/03/2018 em 14:12
fonte usuário

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more