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中使用 Selenium 实现网页截图实例
Jul 18 Python
python基础教程之对象和类的实际运用
Aug 29 Python
pygame学习笔记(3):运动速率、时间、事件、文字
Apr 15 Python
讲解Python中fileno()方法的使用
May 24 Python
Python常用内置模块之xml模块(详解)
May 23 Python
PyQt5固定窗口大小的方法
Jun 18 Python
解决Python3 控制台输出InsecureRequestWarning问题
Jul 15 Python
Python SQLAlchemy入门教程(基本用法)
Nov 11 Python
python中的subprocess.Popen()使用详解
Dec 25 Python
Python sys模块常用方法解析
Feb 20 Python
Python Django路径配置实现过程解析
Nov 05 Python
OpenCV项目实践之停车场车位实时检测
Apr 11 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
Yii2第三方类库插件Imagine的安装和使用
2017/07/06 PHP
php json转换相关知识(小结)
2018/12/21 PHP
Laravel框架源码解析之入口文件原理分析
2020/05/14 PHP
thinkphp5.1 框架导入/导出excel文件操作示例
2020/05/25 PHP
jquery 元素相对定位代码
2010/10/15 Javascript
Jquery中对数组的操作代码
2011/08/12 Javascript
Prototype源码浅析 String部分(三)之HTML字符串处理
2012/01/15 Javascript
jquery索引在使用中的一些困惑
2013/10/24 Javascript
js showModalDialog弹出窗口实例详解
2014/01/07 Javascript
jquery+php实现搜索框自动提示
2014/11/28 Javascript
详解Javacript和AngularJS中的Promises
2016/02/09 Javascript
JavaScript判断数字是否为质数的方法汇总
2016/06/02 Javascript
微信小程序开发探究
2016/12/27 Javascript
JavaScript变量声明var,let.const及区别浅析
2018/04/23 Javascript
angular 实现的输入框数字千分位及保留几位小数点功能示例
2018/06/19 Javascript
js 实现在2d平面上画8的方法
2018/10/10 Javascript
Node.js 多线程完全指南总结
2019/03/27 Javascript
js取0-9随机取4个数不重复的数字代码实例
2019/03/27 Javascript
vue 项目build错误异常的解决方法
2019/04/22 Javascript
layui动态加载多表头的实例
2019/09/05 Javascript
[36:13]Mineski vs iG 2018国际邀请赛小组赛BO2 第一场 8.16
2018/08/17 DOTA
[46:44]DOTA2-DPC中国联赛 正赛 Ehome vs PSG.LGD BO3 第二场 3月7日
2021/03/11 DOTA
利用python实现命令行有道词典的方法示例
2017/01/31 Python
python通过pip更新所有已安装的包实现方法
2017/05/19 Python
python 接口_从协议到抽象基类详解
2017/08/24 Python
python添加菜单图文讲解
2019/06/04 Python
python中字典按键或键值排序的实现代码
2019/08/27 Python
tensorflow之并行读入数据详解
2020/02/05 Python
Python计算信息熵实例
2020/06/18 Python
英语翻译系毕业生求职信
2013/09/29 职场文书
公司行政主管岗位职责
2015/04/09 职场文书
忠犬八公的故事观后感
2015/06/05 职场文书
css3 实现文字闪烁效果的三种方式示例代码
2021/04/25 HTML / CSS
深入探讨opencv图像矫正算法实战
2021/05/21 Python
Python调用腾讯API实现人脸身份证比对功能
2022/04/04 Python
MySQL如何修改字段类型和字段长度
2022/06/10 MySQL