Django用户认证系统如何实现自定义


Posted in Python onNovember 12, 2020

自定义用户认证系统

Django 自带的用户认证系统已经可以满足大部分的情况,但是有时候我们需要某些特定的需求。Django 支持使用其他认证系统、也可以扩展Django的User模块,完全自定义新的认证模块。

参考:https://docs.djangoproject.com/en/2.0/topics/auth/customizing/

a、拷贝以下代码到model文件中:

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

注意:email, name等字段都是可以自定义的

b、在admin.py中添加如下代码:

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',)
  fieldsets = (
    (None, {'fields': ('email', 'password')}),
    ('Personal info', {'fields': ('date_of_birth',)}),
    ('Permissions', {'fields': ('is_admin',)}),
  )
  # add_fieldsets is not a standard ModelAdmin attribute. UserAdmin
  # overrides get_fieldsets to use this attribute when creating a user.
  add_fieldsets = (
    (None, {
      'classes': ('wide',),
      'fields': ('email', 'date_of_birth', 'password1', 'password2')}
    ),
  )
  search_fields = ('email',)
  ordering = ('email',)
  filter_horizontal = ()

# Now register the new UserAdmin...
admin.site.register(MyUser, UserAdmin)
# ... and, since we're not using Django's built-in permissions,
# unregister the Group model from admin.
admin.site.unregister(Group)

C、 在settings.py中添加配置:

AUTH_USER_MODEL = 'customauth.MyUser' #customauth指APP name, MyUser指自定义的用户表model类
(这个时候仍然可以使用django.contrib.auth import authenticate,login,logout 等认证方法,只是保存数据的表不一样)

D、创建超级用户

首先我们要新建一个用户名,用来登陆管理网站,可以使用如下命令:

python manage.py createsuperuser

输入想要使用的用户名:

Username (leave blank to use 'administrator'): user01

输入email:

Email address: (在这里输入你的自己的邮箱帐号)

输入密码,需要输入两次,并且输入密码时不会显示出来:

Password:

Password (again):

当两次密码都相同的时候,就会提示超级帐号创建成功。

Superuser created successfully.

E、使用:

用前一步创建的用户,登陆后台管理系统http://0.0.0.0:8081/admin/

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
python引用DLL文件的方法
May 11 Python
使用apidocJs快速生成在线文档的实例讲解
Feb 07 Python
django js实现部分页面刷新的示例代码
May 28 Python
Django框架多表查询实例分析
Jul 04 Python
pyttsx3实现中文文字转语音的方法
Dec 24 Python
用django设置session过期时间的方法解析
Aug 05 Python
python实现在多维数组中挑选符合条件的全部元素
Nov 26 Python
解决django 向mysql中写入中文字符出错的问题
May 18 Python
python 图像插值 最近邻、双线性、双三次实例
Jul 05 Python
Python ConfigParser模块的使用示例
Oct 12 Python
python爬取股票最新数据并用excel绘制树状图的示例
Mar 01 Python
只用50行Python代码爬取网络美女高清图片
Jun 02 Python
Django自带用户认证系统使用方法解析
Nov 12 #Python
Django多数据库联用实现方法解析
Nov 12 #Python
Django数据库迁移常见使用方法
Nov 12 #Python
python爬虫中PhantomJS加载页面的实例方法
Nov 12 #Python
python调用win32接口进行截图的示例
Nov 11 #Python
python 下载m3u8视频的示例代码
Nov 11 #Python
pytorch简介
Nov 11 #Python
You might like
php 结果集的分页实现代码
2009/03/10 PHP
深入解析php中的foreach函数
2013/08/31 PHP
php的SimpleXML方法读写XML接口文件实例解析
2014/06/16 PHP
ThinkPHP开发框架函数详解:C方法
2015/08/14 PHP
PHP在linux上执行外部命令的方法
2017/02/06 PHP
PHP删除二维数组中相同元素及数组重复值的方法示例
2017/05/05 PHP
jquery1.5.1中根据元素ID获取元素对象的代码
2011/04/02 Javascript
js调用webservice中的方法实现思路及代码
2013/02/25 Javascript
jquery实现加载等待效果示例
2013/09/25 Javascript
JQuery实现倒计时按钮具体方法
2013/11/14 Javascript
JavaScript SetInterval与setTimeout使用方法详解
2013/11/15 Javascript
JavaScript实现Base64编码转换
2016/04/23 Javascript
jQuery实现查找最近父节点的方法
2016/06/23 Javascript
玩转NODE.JS(四)-搭建简单的聊天室的代码
2016/11/11 Javascript
JS判断是否为JSON对象及是否存在某字段的方法(推荐)
2016/11/29 Javascript
jquery实现刷新随机变化样式特效(tag标签样式)
2017/02/03 Javascript
js中的this的指向问题详解
2019/08/29 Javascript
Vue的双向数据绑定实现原理解析
2020/02/17 Javascript
[05:02][DOTA2]DOTA进化论 第一期
2013/09/27 DOTA
python实现的简单RPG游戏流程实例
2015/06/28 Python
python实现用户管理系统
2018/01/10 Python
Tensorflow实现卷积神经网络用于人脸关键点识别
2018/03/05 Python
django 发送邮件和缓存的实现代码
2018/07/18 Python
pycharm的console输入实现换行的方法
2019/01/16 Python
详解Python中正则匹配TAB及空格的小技巧
2019/07/26 Python
python中可以声明变量类型吗
2020/06/18 Python
Linux的文件类型
2012/03/07 面试题
AJAX检测用户名是否存在的方法
2021/03/24 Javascript
三年级音乐教学反思
2014/01/28 职场文书
三月学雷锋月活动总结
2014/04/28 职场文书
工地宣传标语
2014/06/18 职场文书
学雷锋活动总结报告
2014/06/26 职场文书
好的促销活动方案
2014/08/21 职场文书
超市七夕促销活动方案
2014/08/28 职场文书
副校长竞聘演讲稿
2014/09/01 职场文书
社交电商模式的兴起:这些新的商机千万别错过
2019/07/26 职场文书