Django自带一个用户认证系统,用于处理用户账户、群组、许可和基于cookie的用户会话。
Django的认证系统包含了身份验证和权限管理两部分。简单地说,身份验证用于核实某个用户是否合法,权限管理则是决定一个合法用户具有哪些权限。往后,‘认证’这个词同时代指上面两部分的含义。
权限问题我们先不谈,重点先了解身份验证,最起码能实现登录、登出的基本验证,先来了解几个方法
auth模块
from django.contrib import auth
django.contrib.auth 提供了很多方法,这里只简单记录三个
authenticate()
利用authenticate()方法,对用户进行验证。该方法通常接收username与password作为参数。如果认证信息有效,会返回一个User对象(下面会讲)。authenticate()会在User 对象上设置一个属性标识那种认证后端认证了该用户,且该信息在后面的登录过程中是需要的。当我们试图登陆一个从数据库中直接取出来不经过authenticate()的User对象会报错的!
from django.contrib.auth import authenticate user = authenticate(username='john', password='secret')
login(HttpRequest, user)
在视图中,使用认证系统的login()方法登录用户。它接收一个HttpRequest参数和一个User对象参数。该方法会把用户的ID保存在Django的session中。
from 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: login(request, user) # 跳转到成功页面 ... else: # 返回错误 ...
logout(request)
from django.contrib.auth import logout def logout_view(request): logout(request) # Redirect to a success page.
该函数接受一个HttpRequest对象,无返回值。当调用该函数时,当前请求的session信息会全部清除。该用户即使没有登录,使用该函数也不会报错。
说完这三个方法,下面看下方法的主人。
User对象
用户对象是Django认证系统的核心!在Django的认证框架中只有一个用户模型也就是User模型,注意这个User模型是Django自带的,和这个User模型没有任何关系的自定义用户模型是无法使用Django认证系统的功能的!
用户模型主要有下面几个字段:
- username
- password
- first_name
- last_name
创建用户
要创建一个新用户,最直接的办法是使用create_user()
方法:
from django.contrib.auth.models import User user = User.objects.create_user(username='Eric',password='ericpassword',email='eric@163.com')
如果已经启用了Django的admin站点,也可以在后台创建用户。
修改密码
Django默认会对密码进行加密,因此,不要企图对密码进行直接操作。
使用set_password来修改密码:
from django.contrib.auth.models import User u = User.objects.get(username='Eric') u.set_password(password="ericnewpass") u.save()
check_password(password)
不过用户要修改密码的时候,我们应该让其先输入原来的密码,验证通过后再进行修改,check_password()方法做旧密码验证,通过则返回True,所以一个基本修改密码的视图应该是:
def set_pwd(request): user = request.user data={'status':True, 'msg': ''} if request.method == "POST": old_password = request.POST.get('old_password','') new_password = request.POST.get('new_password','') re_password = request.POST.get('re_password','') if user.check_password(old_password): if new_password: if new_password == re_password: user.set_password(new_password) user.save() return redirect('/login/') else: data['status']=False data['msg']='两次输入密码不一致!' else: data['status']=False data['msg']='密码不能为空!' else: data['status']=False data['msg']='旧密码错误!' return render(request, 'set_pwd.html', locals())
后台认证与限制访问
is_authenticated()
每一次请求中都包含一个request.user属性,表示当前用户。如果该用户未登陆,该属性的值是一个AnonymousUser实例(匿名用户),如果已经登录,该属性就是一个User模型的实例。
如果是真正的User对象,那么is_authenticated()返回值恒为True,用于检查用户是否已经通过了认证。在后台用request.user.is_authenticated()判断用户是否已经登录,如果true则可以向前台展示request.user.name。
所以,可以根据用户的登录状态,对其进行访问限制:
- 用户登陆后才能访问某些页面,
- 如果用户没有登录就访问该页面的话直接跳到登录页面
- 用户在跳转的登陆界面中完成登陆后,自动访问跳转到之前访问的地址
def my_page(request): if not request.user.is_authenticated(): return redirect('%s?next=%s' % (settings.LOGIN_URL, request.path))
login_requierd()
这个是django专门用于限制访问的装饰器,因此上例可以这样简单写为
from django,contrib.auth.decorators import login_required @login_required def my_page(request): ...
若用户没有登录,则会跳转到django默认的 登录URL '/accounts/login/ ' (这个值可以在settings文件中通过LOGIN_URL进行修改)。并传递 当前访问url的绝对路径 (登陆成功后,会重定向到该路径)。
AbstractUser
上说的User对象以及方法都是Django内置的,可是如果想自己在models中创建用户表,又想用django内置的验证和限制访问等功能,怎么办呢?
这就需要内置用户类AbstractUser,就是Django内置的一个关于用户操作的类,它极大地方便了我们对model模型中对User用户类的设计。而所谓内置用户类的本质也就是一个封装好的父类,所以使用起来是相当的方便:
from django.db import models from django.contrib.auth.models import AbstractUser class User(AbstractUser): # 继承AbstractUser mobile = models.CharField(max_length=11)
然后在settings中添加行 AUTH_USER_MODEL = "应用名.模型类名"
# 指定本项目的用户模型类 AUTH_USER_MODEL = "blog.User"
这里只是继承了AbstractUser类,并只自定义了一个手机号的字段,而其他字段都不需再定义和设计,就完成了我们需要的模型。
- 因为父类AbstractUser已经包含了username、password、email、first_name、last_name、last_login、date_joined、is_active 、is_staff、is_superuse这些字段,无需再次定义。
- username、password为必选字段,其余可选。
- 手机号字段Django中没有自带,需要我们继承AbstractUser并添加一条手机号字段即可(其他也可自己添加)。
这样就可以使用上面的验证方式进行操作,记住创建用户要用create_user 方法!
来源:博客园
作者:延小梁的笔记本
链接:https://www.cnblogs.com/lymlike/p/11558662.html