Django自带了强大的后台管理应用,包括用户注册、登录及权限管理功能。
对于用户鉴权,一般在服务器端做两件事情:
1.验证用户是否是他说说的用户,且该用户是否合法。
2.验证用户所拥有的权限。
启用鉴权系统:
1.启用session。应为用户鉴权系统需要通过session来处理用户登录等。
2.在settings.py配置文件的INSTALLED_APPS属性中配置'django.contrib.auth'参数,启用该APP(记得同步创建数据库)
3.在settings.py配置文件MIDDLEWARE_CLASSES属性中配置'django.contrib.auth.middleware.AuthenticationMiddleware'参数,有顺序要求,因为中间件的调用有顺序,需在session中间件后面(django2.0后也可在MIDDLEWARE属性进行配置)
使用鉴权系统:
在视图的request参数中,有一个user属性,可以通过它来处理鉴权系统。该属性是一个User对象,若没有登录,则是一个AnonymousUser类实例对象。源码:/site-packages/django/contrib/auth/models.py
该对象内建了很多方便的操作来处理鉴权系统。
例:
is_authenticated():判断用户是否已经登录。返回一个CallableTrue/CallableFalse。
具体的操作可以查看Django源码。AnonymousUser实例模拟了部分的User实例,但不是全部,所以在request.user对象前,先判断该对象的is_authenticated()来判断是AnonymousUser实例还是User实例。
登录登出操作:
验证:
Django鉴权系统提供了一个方法验证用户的用户名和密码是否正确,authenticate(),传入username,password两个参数,若用户名密码正确,则返回User对象,否则返回None。
from django.contrib import auth
user = auth.authenticate(username='john', password='secret')
# 若错误,则user为None
该部分源码在/site-packages/django/contrib/auth/__init__.py,其实际调用了了对应后端进行验证,这个后端配置在settings的AUTHENTICATION_BACKENDS属性中,默认的全局配置为django.contrib.auth.backends.ModelBackend。
登录:
Django鉴权系统使用提供login()方法来进行用户登录,该方法接受一个HttpRequest对象和一个User对象作为参数,通过Django的session会话框架将用户ID保存在该会话中。注:request对象中保存了user id以及backend后端处理器。这样用户就不用在每次请求时重复验证
# 在视图中使用,视图函数接收的第一个参数为HttpRequest对象
# 通过Http请求为POST方式提交数据
def login_view(request):
username = request.POST.get('username', '') # 获取上传的帐号密码数据
password = request.POST.get('password', '')
user = auth.authenticate(username=username, password=password) # 调用authenticate()方法验证数据正确性,注意需从django.contrib中导入auth
if user is not None and user.is_active: # 如果authenticate验证通过且User实例对象处于活跃状态
# Correct password, and the user is marked "active"
auth.login(request, user) # 调用login方法进行用户登录
# Redirect to a success page.
return HttpResponseRedirect("/account/loggedin/")
else:
# Show an error page
return HttpResponseRedirect("/account/invalid/")
注:login函数源码同样在/site-packages/django/contrib/auth/__init__.py中,在登录成功后,会往request.session会话中加入SESSION_KEY、BACKEND_SESSION_KEY、HASH_SESSION_KEY参数,同时若request无user对象,则会将User对象添加到request中。
登出操作:
Django提供logout()方法进行用户登出,该方法接受一个HttpRequest对象,并且没有返回值。且传入的请求用户中即使没有登录,登出操作也不会抛出异常。
源码在/site-packages/django/contrib/auth/__init__.py中,logout()操作会将request中的User实例对象换成AnonymousUser实例,该实例前面已经讲过了,同时刷新request的session会话数据。从而导致下次请求时进行验证登录操作。
注:Django提供了一套鉴权系统,可以不需要自己来开发用户登录登出操作。
对部分视图的访问需要验证用户是否登陆:
如果想在自己的视图中要求用户必须登录才能访问,则可以使用修饰器模式。从django.contrib.auth.decorators导入login_required,使用@修饰符来修饰对应的视图函数。该方法主要完成以下两件事情:
1.如果用户没用登录,则路由重定向到/accounts/login/,并把当前绝对URL作为next在查询字符串中传递过去,例如/accounts/login/?next=/polls/3/
2.如果用户已经登录,则正常执行视图函数。不需要在视图函数中在单独验证用户状态。
对部分视图的访问需要验证用户是否有权限:
Django的User实例对象提供了has_perm()方法来检查是否有相应权限,若有相应权限,则返回True。
另外,Django也提供了permission_required()装饰器,可以用@修饰符来修饰视图函数。该装饰器接受一个参数“待检查的目标权限”,也可以传入一个可选参数login_url,这个参数表示若权限审核不通过则重定向的url路由。该参数默认为/accounts/login/
本文详细介绍了Django框架内置的用户认证系统,包括用户登录、登出流程,以及如何使用装饰器实现视图级别的权限控制。

479

被折叠的 条评论
为什么被折叠?



