zoukankan      html  css  js  c++  java
  • django使用email进行身份验证(转载)

    版权所有,转载请注明出处:http://guangboo.org/2013/03/27/authentication-using-email-in-django

    django自带的验证功能免去了我们的大量工作,它提供了验证、授权相关的接口,我们只有非常少的代码就可以实现,但是django自带的身份验证的方法只能使用用户名来进行验证,如果要想使用email进行验证的话,就需要自己编写一些代码了。

    为使得我们能在使用django提供的验证功能时,能够使用email进行身份验证,本文提出一个简单的解决方案,使尽量少的编写代码,同时又能实现上面的功能。本文使用环境django(1.4.2)+python(2.7.3)。

    django的身份验证授权等功能在模块django.contrib.auth模块下,该模块下提供了默认的验证表单,修改密码,找回密码等表单,验证,登录接口等。其中views.py下提供了login和logout方法,用户登录和注销,当然还包含其他的如登录跳转,重置密码,修改密码等。这些view方法都有很多的参数,都是为了扩展而添加的,这些方法我们可以直接拿来使用,如果我们不考虑email验证或登录界面的话,就可以使用如下代码:

    from django.conf.urls import patterns, include, url
    
    urlpatterns = patterns('',
        url(r'^login/$', 'django.contrib.auth.views.login', name = 'login'),
    )

    只要将上面的三行代码拷贝到urls.py文件中,就可以实现login的功能,只是登录界面是admin的登录界面,并且使用默认的用户名和密码进行验证。如果我们查看django.contrib.auth.views.login方法的源代码的话,就会发现login的方法签名为:

    def login(request, template_name='registration/login.html',
              redirect_field_name=REDIRECT_FIELD_NAME,
              authentication_form=AuthenticationForm,
              current_app=None, extra_context=None)

    login方法有很多参数,并且都是有默认值的,对我们来说,最常用的就是template_name参数了,我们可以这样修改urls.py文件,实现登录界面的自定义。

    urlpatterns = patterns('',
        url(r'^login/$', 'django.contrib.auth.views.login', {'template_name':'account/long.html'}, name = 
    
    'login'),
    )

    与前面的代码比较,在url方法中添加了一个参数 {'template_name':'account/long.html'},该参数就会传递给login方法,从而就实现修改登录界面的目的了。也许你会疑惑,为什么login方法中为什么没有身份验证的代码,其实身份验证的功能是实现在form中的,就是默认的身份验证表单AuthenticationForm,我们继续阅读AuthenticationForm表单的源代码:django.contrib.auth.forms.AuthenticationForm,我们会发现身份验证功能的实现,是在方法clean中,代码如下:

    def clean(self):
            username = self.cleaned_data.get('username')
            password = self.cleaned_data.get('password')
    
            if username and password:
                self.user_cache = authenticate(username=username,
                                               password=password)
                if self.user_cache is None:
                    raise forms.ValidationError(
                        self.error_messages['invalid_login'])
                elif not self.user_cache.is_active:
                    raise forms.ValidationError(self.error_messages['inactive'])
            self.check_for_test_cookie()
            return self.cleaned_data

    其中authenticate方法就是我们要找的验证代码,当然到此我们已经找到验证的实现,我们就可以重写一个验证表单,重新实现clean方法就可以实现我们自己的验证方式--使用email验证,然后在

    {'template_name':'account/long.html'}参数中添加自定义的验证表单类,如:

    urlpatterns = patterns('',
        url(r'^login/$', 'django.contrib.auth.views.login', 
    
    {'template_name':'account/long.html','authentication_form':CustomAuthForm}, name = 'login'),
    )

    其中CustomAuthForm是我们自定义的验证表单,我们可以参考django自动的AuthenticationForm的实现编写我们自己的CustomAuthForm类,这里就不在给出实例,这是一种方法。

    另一种方法,我们定义一个backend类,如下:

    # -*- coding:utf-8 -*-
    # backends.py
    
    from django.contrib.auth.backends import ModelBackend
    from django.contrib.auth.models import User
    
    class EmailCheckModelBackend(ModelBackend):
        def authenticate(self, username = None, password = None, is_staff = None):
            try:
                user = User.objects.get(email = username)
                if user.check_password(password):
                    if is_staff is not None:
                        if user.is_staff == is_staff:
                            return user
                        else:
                            return None
                    return user
                
            except User.DoesNotExist:
                return None

    并且在settings.py文件中添加如下代码即可:

    AUTHENTICATION_BACKENDS = ('account.backends.EmailCheckModelBackend',)

    需要说明的是,authenticate方法签名中的原有参数名称最后不要修改,因为admin的验证方式也会使用该backed,如果你仔细观察AuthenticationForm的clean方法的话,authenticate方法调用是传递了参数名的,如果我们将username参数名该成了email或者其他名称的话,admin就无法登陆了。

  • 相关阅读:
    netcore 发布到IIS上常见错误
    mysql解压文件安装
    VS2017 怎么启用nuget程序包还原?
    vue-qr生成下载二维码
    控制器,action, 过滤器, 权限
    WebSocket浅析(一):实现群聊功能
    BOM元素之window对象
    arguments及arguments.callee
    Spring入门6事务管理2 基于Annotation方式的声明式事务管理机制
    Spring入门5.事务管理机制
  • 原文地址:https://www.cnblogs.com/tk091/p/4012685.html
Copyright © 2011-2022 走看看