django1.11自定义身份验证后端问题--返回一个以/user/xxx开头的未知URL



我尝试使用Django 1.11中的自定义身份验证后端来构建该功能(使用用户的电子邮件登录,而不是使用用户名常规登录。用户名和用户电子邮件都保存在数据库中的同一用户对象中)。

使用以下代码,我可以成功地使用用户名(我在HTML表单的username空白中输入正确的用户名值)和密码成对登录。但反过来,当我使用HTML表单输入的电子邮件值时,它会在后台调试窗口中弹出如下错误:

error"未找到:/user/login/;
"POST/user/login/HTTP/1.1"404">

我很好奇,因为在我的整个urls.py和users.views.py中从来没有"user/login"。它是怎么来的?

在本次询问帮助之前,我在Django官方文档(1.11版)中查找了堆栈溢出中的其他提示性注释,但它仍然没有正确的答案。

希望你们的人能救我出来,说出你们的想法。

顺便说一句,我还查看了1.11 Django文档,上面说">

Do not forget to test for the is_active attribute of the user in your own backend permission methods.
Changed in Django 1.10:
In older versions, the ModelBackend allowed inactive users to authenticate.

所以我曾经试图根据"is_acitve"检查来解决这个错误,但不幸的是,我还没有修复它。

--更新:在MySQL数据库中,我注意到当前用户对象有字段

(is_staff =1; is_active=1)

但我不知道如何使用这些信息来解决我目前的问题。

我在Pycharm IDE、Djang1.11、py3.6、mysql5.7(作为保存用户表的DB)中运行了它

-重要更新

:最初我的测试浏览器是google chrome,在采用了以下Ruddra的更正建议后,新代码可以在浏览器(MS edge和firefox)中成功解决问题,但在google chrome中仍然没有。所以现在我更喜欢将这个问题归类为"

Django 1.11自定义身份验证后端与chrome浏览器发生冲突">

在设置.py,

AUTHENTICATION_BACKENDS=(#'django.contrib.auth.backends.ModelBackend','django.contrib.auth.backends.ModelBackend',)INSTALLED_APPS=['django.contrib.admin','django.contrib.auth','django.contrib.contenttypes','django.contrib.sessions','django.contrib.messages','django.contrib.staticfiles','用户',"课程",'组织','操作',"xadmin","crispy_forms","DjangUeditor",]AUTH_USER_MODEL="users.UserProfile"模板=[{"BACKEND":"django.template.backends.django.DjanoTemplates","DIRS":[os.path.join(BASE_DIR,"templates')],"APP_DIRS":真,"选项":{'context_processors':['django.template.context_processors.debug','django.template.context_processors.request','django.contrib.auth.context_processors.auth','django.contrib.messages.context_processors.messages','django.template.context_processors.media',],},},]

在urls.py,中

从django.conf.uls导入url,包括来自django.ntrib导入管理从django.views.generic导入TemplateView导入xadmin从.settings导入MEDIA_ROOT来自django.views.static导入服务来自用户。视图导入user_loginurl模式=[url(r'^xadmin/',xadmin.site.urls),url(r'^media/(?P.*)$',serve,{"document_root":media_root}),url('^$',TemplateView.as_view(template_name='index.html'),name='index'),url('^login/$',user_login',name='登录'),name='pload'),]

在users.views.py,中

来自django.shortcuts导入渲染从django.contrib.authenticate导入,登录从django.contrib.auth.backends导入ModelBackend从django.db.models导入Q从.models导入UserProfile类CustomBackend(ModelBackend):def authenticate(self、request、username=None、password=None,**kwargs):尝试:user=UserProfile.objects.get(Q(用户名=用户名)|Q(电子邮件=用户名))if user.check_password(密码):返回用户除了UserProfile。DoesNotExist as e:return无def user_login(请求):如果request.method=="POST":user_name=请求。POST.get("username",")pass_word=请求。POST.get("password",")user=authenticate(用户名=user_name,密码=pass_word)如果用户不是"无":登录(请求,用户)return render(请求,"index.html")其他:return render(request,"login.html",{"msg":"name or password erro!"})elif request.method=="GET":在login.html,中返回render(request,"login.html",{})

[

form action="/login/" method="post" id="jsLoginForm" autocomplete="off">
	input type='hidden' name='csrfmiddlewaretoken' value='mymQDzHWl2REXIfPMg2mJaLqDfaS1sD5' />
	div class="form-group marb20">
		label>your name</label>
		input name="username" id="account_l" type="text" placeholder="手机号/邮箱" />
	/div>
	div class="form-group marb8">
		label>your password</label>
		input name="password" id="password_l" type="password" placeholder="please input your password" />
	/div>
	div class="error btns login-form-tips" id="jsLoginTips">{{ msg }}</div>
	 div class="auto-box marb38">
		label><input type="checkbox" id="jsAutoLogin"> instant login </label>
		a class="fr" href="forgetpwd.html">forget your password?</a>
	 /div>
	 input class="btn btn-green" id="jsLoginBtn" type="submit" value="instant login > " />
{% csrf_token %}
/form>

]

在理想的情况下,在我以HTML形式输入正确的用户电子邮件值和密码值后,按下"登录"按钮,然后我假设我可以登录到index.HTML,因为我使用相同的用户名和用户密码作为一对进行身份验证

不确定这里可能出了什么问题,我猜,您的一个视图受到装饰器或LoginRequiredMixin的保护,该视图可能配置有user/login路由。

您还缺少一件事,那就是将CustomBackend添加到您的AUTHENTICATION_BACKENDS

AUTHENTICATION_BACKENDS = (
'your_app.views.CustomBackend',
'django.contrib.auth.backends.ModelBackend', 
)

同样在该视图中,与其在登录成功时呈现index.html,不如重定向到主页:

def user_login(request):
if request.method == "POST":
user_name = request.POST.get("username", "")
pass_word = request.POST.get("password", "")
user = authenticate(username=user_name, password=pass_word)
if user is not None:
login(request, user)
return redirect(reverse('index'))
else:
return render(request, "login.html", {"msg": "name or password erro!"})
elif request.method == "GET":
return render(request, "login.html", {})

此外,更新login_html如下:

<form action="{% url 'login' %}" method="post" id="jsLoginForm" autocomplete="off">

相关内容

最新更新