1、Django自带用户认证系统
Django自带用户认证系统,这个系统支持访问控制、注册用户、关联创建者和内容等;在开发用户认证功能时的时候,可以使用Django自带用户认证系统实现;
A、相关表
在使用"python manage.py makemigrationss"和"python manage.py migrate"迁移完成数据库之后
根据配置文件settings.py中的数据库段生成的数据表中已经包含了6张进行认证的数据表,分别是
- auth_user
- auth_group
- auth_group_permissions
- auth_permission
- auth_user_groups
- auth_user_user_permissions
自带用户认证系统,进行用户认证的数据表为auth_user(用户的数据保存在这个表里)
https://docs.djangoproject.com/en/2.0/topics/auth/customizing/
B、使用Django自带的认证功能
B.1 首先要导入auth模块:from
django.contrib
import
auth
django.contrib.auth常用的三个方法:
authenticate():提供了用户认证,即验证用户名以及密码是否正确,一般需要username和password两个关键字参数
如果通过认证,authenticate()
函数会返回一个User对象。
当我们试图登陆一个从数据库中直接取出来不经过authenticate()
的User对象时会报错。
B.2 创建用户
user对象
User对象属性:username,password为必填项
password用哈希算法保存到数据库中
- is_staff:判断用户是否拥有网站的管理权限
- is_active:判断是否允许用户登陆,设置为“False”时可以不用删除用户来禁止用户登陆
使用create_user辅助函数创建用户
login(request)登陆用户
这个函数使用Django的session框架给某个已认证的用户附加上session_id信息。
from
django.shortcuts
import
render,redirect,HttpResponse
from
django.contrib.auth
import
authenticate,login
def
auth_view(request):
username
=
request.POST.GET(
"usernmae"
)
# 获取用户名
password
=
request.POST.GET(
"password"
)
# 获取用户的密码
user
=
authenticate(username
=
username,password
=
password)
# 验证用户名和密码,返回用户对象
if
user:
# 如果用户对象存在
login(request,user)
# 用户登陆
return
redirect(
"/index/"
)
else
:
return
HttpResponse(
"用户名或密码错误"
)
logout(request)注销用户
这个函数接受一个HttpResponse对象,无返回值。
当调用该函数时,当前请求的session信息全部被清除。
即使当前用户没有登陆,调用该函数也不会报错。
使用:
from
django.shortcuts
import
render,redirect,HttpResponse
from
django.contrib.auth
import
authenticate,login,logout
def
logout_view(request):
logout(request)
# 注销用户
return
redirect(
"/index/"
)
user对象的is_authenticated()
要求:
- 用户登陆后才能访问某些页面
- 如果用户没有登陆就访问本应登陆才能访问的页面时会直接跳转到登陆页面
- 用户在登陆页面登陆后,又会自动跳转到之前访问的页面
def
view(request):
if
not
request.user.is_authenticated():
return
redirect(
"/login/"
)
user对象的login_requierd()
装饰器
from
django.contrib.auth.decorators
import
login_required
@login_required
def
views(request):
pass
from
django.contrib.auth.models
import
User
class UserProfile(models.Model):
user = models.OneToOneField(User,on_delete=models.CASCADE) # django自带用户表User模块和自定义的用户关联
name = models.CharField(max_length=32)
def __str__(self):
return self.name
3、自定义用户认证系统
from django.db import models
from django.contrib.auth.models import ( BaseUserManager, AbstractBaseUser )
class MyUserManager(BaseUserManager):
def create_user(self, email, name, password=None):
"""
Creates and saves a User with the given email, date of
birth and password.
"""
if not email:
raise ValueError('Users must have an email address')
user = self.model(
email=self.normalize_email(email),
name=name,
)
user.set_password(password)
user.save(using=self._db)
return user
def create_superuser(self, email, name, password):
"""
Creates and saves a superuser with the given email, date of
birth and password.
"""
user = self.create_user(
email,
password=password,
name=name,
)
user.is_admin = True
user.save(using=self._db)
return user
class UserProfile(AbstractBaseUser):
'''账号表'''
email = models.EmailField(
verbose_name='email address',
max_length=255,
unique=True,
)
name = models.CharField(max_length=32)
is_active = models.BooleanField(default=True)
is_admin = models.BooleanField(default=False)
objects = MyUserManager()
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = ['name']
def __str__(self):
return self.email
def has_perm(self, perm, obj=None):
"Does the user have a specific permission?"
# Simplest possible answer: Yes, always
return True
def has_module_perms(self, app_label):
"Does the user have permissions to view the app `app_label`?"
# Simplest possible answer: Yes, always
return True
@property
def is_staff(self):
"Is the user a member of staff?"
# Simplest possible answer: All admins are staff
return self.is_admin
from django import forms
from django.contrib import admin from django.contrib.auth.models import Group from django.contrib.auth.admin import UserAdmin as BaseUserAdmin from django.contrib.auth.forms import ReadOnlyPasswordHashField from customauth.models import MyUser class UserCreationForm(forms.ModelForm): """A form for creating new users. Includes all the required fields, plus a repeated password.""" password1 = forms.CharField(label='Password', widget=forms.PasswordInput) password2 = forms.CharField(label='Password confirmation', widget=forms.PasswordInput) class Meta: model = MyUser fields = ('email', 'date_of_birth') def clean_password2(self): # Check that the two password entries match password1 = self.cleaned_data.get("password1") password2 = self.cleaned_data.get("password2") if password1 and password2 and password1 != password2: raise forms.ValidationError("Passwords don't match") return password2 def save(self, commit=True): # Save the provided password in hashed format user = super().save(commit=False) user.set_password(self.cleaned_data["password1"]) if commit: user.save() return user class UserChangeForm(forms.ModelForm): """A form for updating users. Includes all the fields on the user, but replaces the password field with admin's password hash display field. """ password = ReadOnlyPasswordHashField() class Meta: model = MyUser fields = ('email', 'password', 'date_of_birth', 'is_active', 'is_admin') def clean_password(self): # Regardless of what the user provides, return the initial value. # This is done here, rather than on the field, because the # field does not have access to the initial value return self.initial["password"] class UserAdmin(BaseUserAdmin): # The forms to add and change user instances form = UserChangeForm add_form = UserCreationForm # The fields to be used in displaying the User model. # These override the definitions on the base UserAdmin # that reference specific fields on auth.User. list_display = ('email', 'date_of_birth', 'is_admin') list_filter = ('is_admin',)