首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >django:无法运行自定义身份验证后端

django:无法运行自定义身份验证后端
EN

Stack Overflow用户
提问于 2014-05-09 06:36:24
回答 1查看 1.2K关注 0票数 0

我创建了一个自定义身份验证后端并试图运行它,但是我发现它不运行自定义身份验证,并且返回一个错误。

下面是源代码。

settings.py

代码语言:javascript
运行
复制
AUTH_USER_MODEL = 'welcome.NDDUser'

AUTHENTICATION_BACKENDS = (
    'welcome.backend.MyCustomBackend',
)

welcome/backend.py

代码语言:javascript
运行
复制
from welcome.models import NDDUser

from django.core.exceptions import ValidationError

class MyCustomBackend(object):
    # Create an authentication method
    # This is called by the standard Django login procedure.
    def authenticate(self, username=None, password=None):
        try:
            # Try to find a user matching your name
            user = NDDUser.objects.get(username=username)
        except NDDUser.DoesNotExist:
            return None

        if user.check_password(password):
            return user
        else:
            return None

    def get_user(self, user_id):
        try:
            return NDDUser.objects.get(pk=user_id)
        except NDDUser.DoesNotExist:
            return None

welcome/views.py

代码语言:javascript
运行
复制
from django.contrib.auth import authenticate, login

from django.shortcuts import render, redirect

from welcome.models import NDDUser, University

from welcome.forms import LoginForm, RegisterForm

def index(request):
    if request.method == 'POST':
        email = request.POST.get('email')
        password = request.POST.get('password')

        user = authenticate(email=email, password=password)

        if user is not None:

            login(request, user)
            # Redirect to doctor search page.
            return redirect('search:index')
        else:
            context = { 'login_error_message' : 'You put the wrong information'}
            return render(request, 'welcome/index.html', context)
    else:
        return render(request, 'welcome/index.html')

welcome/forms.py

代码语言:javascript
运行
复制
from django import forms

class LoginForm(forms.Form):
    email = forms.CharField()
    password = forms.CharField()

class RegisterForm(forms.Form):
    university = forms.CharField()
    email = forms.CharField()
    password1 = forms.CharField(min_length=6)
    password2 = forms.CharField(min_length=6)
    nickname = forms.CharField(max_length=15, min_length=2)

    def clean(self):
        cleaned_data = super(RegisterForm, self).clean()
        password1 = cleaned_data.get('password1')
        password2 = cleaned_data.get('password2')

        if password1 and password2:
            if password1 != password2:
                raise forms.ValidationError("Both passwords r not same.")

        return cleaned_data

welcome/models.py

代码语言:javascript
运行
复制
from django.db import models
from django.contrib.auth.models import (
                                        BaseUserManager, AbstractBaseUser
                                        )
from django.core.exceptions import ValidationError

class NDDUserManager(BaseUserManager):
    def create_user(self, email, university, password, nickname):
        user = self.model(
                          email=NDDUserManager.normalize_email(email),
                          university=university,
                          nickname=nickname,
                          )

        user.set_password(password)
        #user.full_clean()
        #user.save()
        try:
            user.full_clean()
        except ValidationError as e:
            return e

        user.save()    
        return user

class NDDUser(AbstractBaseUser):
    university = models.ForeignKey('University')
    email = models.EmailField(unique=True, error_messages={'invalid' : 'Invalid mail address','unique' : 'Already registered email address'})
    nickname = models.CharField(max_length='15', unique=True, error_messages={'unique' : 'Already registered nickname'})

    objects = NDDUserManager()

    USERNAME_FIELD = 'email'
    REQUIRED_FIELDS = ['university', 'password', 'nickname']


class University(models.Model):
    name = models.CharField(max_length='20')
    email = models.CharField(max_length='20')

    def __unicode__(self):
        return u'%s %s' % (self.name, self.email)

直到写完所有的代码我才开始syncdb。最后,在syncdb并通过eclipse运行它之后(使用pydev),我将面临下面的错误消息:

代码语言:javascript
运行
复制
ERROR    2014-05-09 06:15:49,448 base.py:212] Internal Server Error: /welcome/
Traceback (most recent call last):
  File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/lib/django-1.5/django/core/handlers/base.py", line 115, in get_response
    response = callback(request, *callback_args, **callback_kwargs)
  File "/Users/nextdoordoctor/git/NDDWeb/NDDWeb/src/welcome/views.py", line 19, in index
    user = authenticate(email=email, password=password)
  File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/lib/django-1.5/django/contrib/auth/__init__.py", line 60, in authenticate
    user = backend.authenticate(**credentials)
  File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/lib/django-1.5/django/contrib/auth/backends.py", line 16, in authenticate
    user = UserModel._default_manager.get_by_natural_key(username)
  File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/lib/django-1.5/django/contrib/auth/models.py", line 168, in get_by_natural_key
    return self.get(**{self.model.USERNAME_FIELD: username})
  File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/lib/django-1.5/django/db/models/manager.py", line 143, in get
    return self.get_query_set().get(*args, **kwargs)
  File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/lib/django-1.5/django/db/models/query.py", line 398, in get
    num = len(clone)
  File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/lib/django-1.5/django/db/models/query.py", line 106, in __len__
    self._result_cache = list(self.iterator())
  File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/lib/django-1.5/django/db/models/query.py", line 317, in iterator
    for row in compiler.results_iter():
  File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/lib/django-1.5/django/db/models/sql/compiler.py", line 775, in results_iter
    for rows in self.execute_sql(MULTI):
  File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/lib/django-1.5/django/db/models/sql/compiler.py", line 840, in execute_sql
    cursor.execute(sql, params)
  File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/lib/django-1.5/django/db/backends/util.py", line 41, in execute
    return self.cursor.execute(sql, params)
  File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/lib/django-1.5/django/db/backends/mysql/base.py", line 130, in execute
    six.reraise(utils.DatabaseError, utils.DatabaseError(*tuple(e.args)), sys.exc_info()[2])
  File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/lib/django-1.5/django/db/backends/mysql/base.py", line 120, in execute
    return self.cursor.execute(query, args)
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/MySQL_python-1.2.4b4-py2.7-macosx-10.6-intel.egg/MySQLdb/cursors.py", line 202, in execute
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/MySQL_python-1.2.4b4-py2.7-macosx-10.6-intel.egg/MySQLdb/connections.py", line 36, in defaulterrorhandler
DatabaseError: (1146, "Table 'nddweb.auth_user' doesn't exist")
INFO     2014-05-09 06:15:49,548 module.py:639] default: "POST /welcome/ HTTP/1.1" 500 12787

-更多的信息

最后,我将AUTH_USER_MODEL定义放在settings.py和syncdb的顶部,它可以工作!没有像上面那样的错误输出。但我还有另外一个问题。

当我单击form和post数据的submit按钮时,r发送到view.py和authenticate()函数不能正常工作。

即使我键入正确的表单数据并发送它,仍然输出“您输入了错误的信息”。我想Django并没有真正导入MyCustomBackend ..。

我该如何解决这个问题?

EN

回答 1

Stack Overflow用户

发布于 2014-05-09 09:53:09

你的方法签名不匹配。后端需要一个username和一个password,但是在您的视图中,您尝试使用emailpassword对用户进行身份验证。

使用不支持的关键字调用MyCustomBackend.authenticate将引发TypeError。Django对此的处理与后端返回None时相同。这样,多个后端可以接收不同的关键字参数,并且仍然可以正常工作。

还请注意,尽管已经设置了USERNAME_FIELD属性,但用户模型仍然没有username字段。它只在get_username方法和经理的get_by_natural_key方法中使用。在所有其他情况下,仍然需要对实际的email字段进行筛选。

顺便说一句,目前您的自定义后端没有做默认Django后端不做的任何事情。除非您需要添加更多的自定义功能,否则请考虑使用默认后端。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/23558082

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档