django的用户认证

首先的两个中间件

sessions.middleware.SessionMiddleware’, 和 AuthenticationMiddleware 中间件再创建项目的时候会自动注册到系统中的

MIDDLEWARE_CLASSES = (
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.locale.LocaleMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.transaction.TransactionMiddleware',
)

有了这两个中间件,在view中,我们就可以使用request.user获取当前的登陆用户User对象。如果当前用户没有登陆,那么request.user将会是我们之前所说的AnonymousUser对象。我们可以用User对象的is_authenticated()方法将这两者区分开来:

if request.user.is_authenticated():
    # 针对验证用户.
else:
    # 对于匿名未登录用户

登陆一个用户

需要两个函数:authenticate(username,password)和login(request,user),位于django.contrib.auth模块中;这两个方法需要结合使用,

  1. authenticate(username,password)函数需要两个参数username,password,如果校验通过则返回User对象,如果校验不通过返回None,例如:
from django.contrib.auth import authenticate
user = authenticate(username='john', password='secret')
if user is not None:
    if user.is_active:
        print "You provided a correct username and password!"
    else:
        print "Your account has been disabled!"
else:
    print "Your username and password were incorrect."
  1. .login()方法接受两个参数,第一个是request对象,第二个是验证后的user对象。login方法使用SessionMiddleware将userID存入session当中。注意,在用户还未登录的时候,也存在着匿名用户的Session,在其登陆之后,之前在匿名Session中保留的信息,都会保留下来。这两个方法要结合使用,而且必须要先调用authenticate(),因为该方法会User的一个属性上纪录该用户已经通过校验了,这个属性会被随后的login过程所使用,例如:
rom django.contrib.auth import authenticate, login

def my_view(request):
    username = request.POST['username']
    password = request.POST['password']
    user = authenticate(username=username, password=password)
    if user is not None:
        if user.is_active:
            login(request, user)
            # 跳转到成功页面.
        else:
            # 返回一个无效帐户的错误
    else:
        # 返回登录失败页面。

另外的登录方法

也可以不用authenticate()进行特定于一个用户的身份校验,直接使用和User无关的几个函数进行密码相关的校验,在Django1.4中以及新版本中提供以下方法,位于模块django.contrib.auth.hasherscheck_password(password,encoded):第一个参数是明文密码,第二个参数是加密过的密码。如果通过校验返回True,不通过返回False;  
make_password(password[,salt,hashers]):根据给定的明文密码,salt,和Django支持的加密算法,返回一个加密的密码。如果password提供的值为None,那么该返回值将永远通不过check_password()方法。这个返回值是一个特定的约定值,目前是'!';
is_password_usable(encoded_password):判断是否给定字符串是一个hashed密码,有机会通过check_password()函数的校验。

登出(log out)一个用户

我们使用django.contrib.auth.logout函数来登出用django.contrib.auth.login函数登入的用户。

logout(requet)

函数只有一个参数,就是request。没有返回值,而且即使当前用户没有登陆也不会抛出任何异常。

例子:
from django.contrib.auth import logout

def logout_view(request):
    logout(request)
    # 重定向到成功登出界面

注意:

这个方法,会将存储在用户session的数据全部清空,这样避免有人用当前用户的浏览器登陆然后就可以查看当前用户的数据了,回想一下login会保留anonymous用户的session数据。如果需要将一些东西加入到登出之后的用户session,那么需要在logout方法调用之后再进行。

Login和Logout的两个signals

Django的signal体系是一套简单实用的事件定义、事件产生、事件监听、事件处理框架,具体可以参看Django关于signal的文档。在登陆和登出这两个重要的点上,提供了两个signal:

django.contrib.auth.signals.user_logged_in
django.contrib.auth.signals.user_logged_out
有三个参数会随singal传过来:

sender:user的class,如果是logout事件该值有可能是None如果用户根本就没有验证通过。
request:HttpRequest对象
user:user对象,如果是logout事件该值有可能是None如果用户根本就没有验证通过。

一个经常性的简单需求就是控制某些view(struts中叫做action方法)只对登陆用户开放,如果未登录用户请求该view则跳转到登录界面让其登陆。要做到这一点,我们可以这样做:

from django.http import HttpResponseRedirect

def my_view(request):
    if not request.user.is_authenticated():
        return HttpResponseRedirect('/login/?next=%s' % request.path)
    # ...
  也可以这样做,返回一个错误的页面:
def my_view(request):
    if not request.user.is_authenticated():
        return render_to_response('myapp/login_error.html')
    # ...

 更为优雅的方式是用decorator:

django.contrib.auth.decorators.login_required([redirect_field_name=REDIRECT_FIELD_NAME,login_url=None])
login_required()装饰器函数做了以下事情:
如果当前用户没有登陆,跳转到settings.LOGIN_URL,并传递当前的绝对路径到URL请求参数中,例如:/accounts/login/?next=/polls/3/
如果当前用户已经登陆了,执行view方法。在view中的方法可以认为当前用户已经登陆了。

login_required方法接受两个参数:

redirect_field_name:默认值是next。用来定义登陆成功之后的跳回之前访问界面的url。
login_url:默认值是settings.LOGIN_URL。用来指定登陆界面的url。如果不传入改参数,就需要确保settings.LOGIN_URL的值是正确设置的。
没有参数的login_required装饰器使用方法:

from django.contrib.auth.decorators import login_required

@login_required
def my_view(request):
    ...
传递参数的方法:

from django.contrib.auth.decorators import login_required

@login_required(redirect_field_name='my_redirect_field')
def my_view(request):
    ...
from django.contrib.auth.decorators import login_required

@login_required(login_url='/accounts/login/')
def my_view(request):
...

以上就是Django提供的用于完成login和logout相关的一些API支持,使用他们可以很好的对用户进行认证了,也就是说用户是谁系统已经搞清楚了,接下来就是更细粒度的判断,判断此人究竟能做些什么,也就是Permission许可的使用了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章