Javascript Django身份验证和Ajax—需要登录的URL
我想给我的Django编码的网站增加一些细节 在Django代码中,我使用Javascript Django身份验证和Ajax—需要登录的URL,javascript,python,django,authentication,Javascript,Python,Django,Authentication,我想给我的Django编码的网站增加一些细节 在Django代码中,我使用Django.contrib.auth.decorators中的@login\u requireddecorator标记哪个视图需要身份验证。未经身份验证的用户单击时的默认行为是将其重定向到登录页面,然后传递目标页面 我在一些网站上看到的,并且我非常喜欢的是,当用户点击一个链接,指向一个仅限于登录用户的地方,而不是重定向到登录页面时,他/她会得到一个弹出窗口(通过JavaScript),要求他/她登录或注册。没有重定向部分
Django.contrib.auth.decorators
中的@login\u required
decorator标记哪个视图需要身份验证。未经身份验证的用户单击时的默认行为是将其重定向到登录页面,然后传递目标页面
我在一些网站上看到的,并且我非常喜欢的是,当用户点击一个链接,指向一个仅限于登录用户的地方,而不是重定向到登录页面时,他/她会得到一个弹出窗口(通过JavaScript),要求他/她登录或注册。没有重定向部分,因此,如果用户认为他/她真的不喜欢该网站而浪费注册时间,则无需使用“后退”键
因此,问题是:您如何管理自动将某些链接标记为“受限”的任务,以便JavaScript能够处理它们的
onclick
事件并显示“请登录”弹出窗口 听起来像是一个页面模板
传递链接\u(或其他内容),您可以通过onClick=“return popup(this,'arg')”
或None
提供该链接。每个链接都是
- 对于匿名会话,
LINK\u VIA
有一个值
- 对于登录会话,
LINK\u VIA
为无
标记周围使用{%if%}
语句。这似乎有些罗嗦{%link\u via%}
编写自己的自定义标记。我对此不太熟悉,但您可以提供链接和文本作为字符串,您的标记可以生成两种链接中的一种<a href="{{link}}" onclick="return login_popup()">
通过它的
如果模板不知道哪些URL需要用户登录,您可能需要重新考虑您的设计
如果必须的话,我想您可以像DjangoURL调度器一样发现视图函数
请参阅:django.core.urlResolver
一旦你掌握了查看功能,你可以检查它是否用@login\u required修饰
这可能会在自定义标记中完成
如果您使用Jinja2,您不需要标签,只需实现该功能并将其公开给环境,这很简单,但您需要阅读一下Jinja2的API)我也面临同样的问题,而且,和您一样,我想要一个简单的装饰器来包装DjangoAjax视图,以便以与其他视图相同的方式处理身份验证。一种对我来说似乎很有希望的方法是将这种装饰器与JavaScript结合使用,以在响应中查找特定值
这是装饰师的第一份修订稿:
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
以下是视图:
@ajax_login_required
def ajax_update_module(request, module_slug, action):
# Etc ...
return HttpResponse(json, mimetype='application/json')
下面是JavaScript(jQuery):
编辑:我已尝试按照建议使用functools.wrapps
。我还没有在工作代码中实际使用过这个装饰器,所以要小心可能的bug。这里是建议的带有wrap的装饰器版本。\uuu doc\uuu,wrap.\uu 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
基于解决方案构建,但适用于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
我想知道的是,如何从模板的角度确定链接指向的视图是否用@login\u required修饰…模板没有随机链接。它有您在模板中专门设计和编码的特定链接。我建议您更改模板中专门放置的每个链接。可能值得指出的是,您可以使用functools.wrapps
def wrappdecorator,以避免分配给wrapp.\uuu doc\uuuuuuuuuu
、wrapp.\uuu dict\uuuuuuuuuu
和wrapp.\uu name\uuuuuuuuu
(本回答中未提及,但应这样做)。请参见@Anders:请继续编辑响应以合并更改。我已经有一段时间没有使用Python了,我不想把它搞砸。视图不应该改为发送401 HTTP状态吗?我不确定为什么这是可接受的答案。这只适用于ajax请求。如果用户单击链接访问受限视图会怎么样?您是否应该更改所有相关的客户端代码以使用initiate ajax请求?我在这一点上迟到了很多,但不管怎样:这是不理想的,因为用户可以直接链接到相关页面,在这种情况下,需要登录的弹出式方法将中断。
# 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