Django认证系统的组成部分:
User(用户)
Permission(许可,定义一个用户的权限)
Group(组,分配批量用户的权限)
非Django认证系统的业务范围(需要使用第三方工具):
密码强度检查
登录请求限制
第三方认证
...
Django认证系统的配置项
在INSTALLED_APPS中:
'django.contrib.auth' #认证框架的核心以及默认模型
'django.contrib.contenttypes' #内容类型系统,用于给模型关联许可
(已默认添加)
在MIDDLEWARE中:
'django.contrib.sessions.middleware.SessionMiddleware' #通过请求管理会话
'django.contrib.auth.middleware.AuthenticationMiddleware' #将会话和用户关联
(已默认添加)
配置完成后,运行migrations命令,创建和认证系统相关的数据表。
在settings.py中:
LOGIN_URL = #设置认证失败的跳转页面
LOGIN_REDIRECT_URL = #设置登录成功的跳转页面
User模型的字段
username(必填,30)
password(必填,明文密码的hash)
email(可选)
first_name(可选,30)
last_name(可选,30)
groups(多对多)
user_permissions(多对多)
is_staff(Boolean类型,判断用户是否可以登录admin site)
is_active(Boolean类型,判断用户是否为激活状态,删除账户的时候可以将该属性设为False,而不直接删除,这样能保留引用到该用户的外键)
is_superuser(Boolean类型,判断用户是否拥有所有的许可)
last_login(datetime类型,用户最近登录时间)
date_joined(datetime类型,用户创建时间)
只有Django自带的User模型能使用认证系统功能,所以我们的用户模型直接利用或继承于Django的User模型:
from django.contrib.auth.models import User
创建用户
直接创建User实例,create_user(username, email=None, password=None):
user = User.objects.create_uer(‘<用户名>’, ‘<用户邮箱>’, ‘<密码>’)
user.is_staff = True #此行可选,让用户有权登录admin
user.save()
#创建一个is_active=True(已激活)的实例对象,以后通过修改对象的属性来修改用户
创建超级用户
python manage.py createsuperuser
修改密码
详见Admin笔记-修改密码。
千万不能直接给User对象的password属性赋值。
用户验证和登录
用户验证:authenticate(username=None, password=None, **kwargs),该方法返回通过认证的User类对象(如果有多个对象通过认证就返回多个对象),如果没有用户通过认证或产生PermissionDenied异常,则返回None。
用户登录:login(request, user),该方法会使用SessionMiddleware把用户ID存入session中。
from django.contrib.auth import authenticate, login
def login_user(request):
form = LoginForm(request.POST) #表单事先写了某些验证规则,将表单实例化
if form.is_valid(): #先用表单进行用户输入的格式验证,如果格式合法,查询数据库
user_name = request.POST.get(‘user_name’, ‘’)
pass_word = request.POST.get(‘pass_word’, ‘’)
user = authenticate(username=user_name, password=pass_word)
if user is not None:
if user.is_active:
login(request, user)
return renser(request, ‘登录成功页面’)
else:
return render(request, ‘账户无效/密码错误页面’, {‘msg’: ‘用户名或密码错误’} )
else:
return renser(request, ‘输入无效页面’, {‘form’: form} ) #表单返回给用户重新输入
#前端页面的样式:{% for value in form.values %} {{ value }} {% endfor %}
#展示用户不规范的输入
注销当前的用户登录
from django.contrib.auth import logout
logout(request)
#即使当前用户未登录也不产生异常,logout后,用户的session数据将被清空。
匿名用户AnonymousUser
用户未登录的时候,request.user属性值就是匿名用户AnonymousUser的实例,匿名用户的特点:
id = None
is_anoymous()为True
is_authenticated()为False
判断某用户是否登录
每一次用户请求中都包含一个request.user属性,判断方法:
if request.user.is_authenticated():
#用户已登录的操作...
else:
#用户未登录的操作...
注意,Django 1.11使用is_authenticated(),Django 2.0使用is_authenticated
用装饰器限制用户权限
@login_required(redirect_field_name=next, login_url=settings.LOGIN_URL)
redirect_field_name:定义登录成功后跳转到之前访问的url
login_url:指定登录界面的url
如果用户登录,执行被装饰的views视图;如果用户未登录,将重定向到settings.LOGIN_URL,并传递当前的url到请求参数中,如/accounts/login/?next=/xxx/。
from django.contrib.auth.decorators import login_required
@login_required
def some_view(request):
# ...
自定义authenticat方法
在views.py中编写类:
from django.contrib.auth.backends import ModelBackend
class CustomBackend(ModelBackend):
def authenticate(self, request, username=None, password=None, **kwargs):
#自定义的认证逻辑...
在settings.py中注册:
AUTHENTICATION_BACKENDS = (
‘<CustomBackend的引用路径>’,
)
用UserProfile储存用户的额外信息
①定义UserProfile模型:
from django.contrib.auth.models import user
class UserProfile(models.Model):
user = models.OneToOneField(User) #创建和User的一对一关系
#额外的属性...
②在settings.py中:
AUTH_PROFILE_MODULE = ‘<应用名>.<UserProfile>’
此时,User对象的get_profile()方法就会返回对应的UserProfile对象。