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实现批量转换文件编码的方法
Jul 28 Python
详解Python的Flask框架中的signals信号机制
Jun 13 Python
Fabric 应用案例
Aug 28 Python
python 内置函数filter
Jun 01 Python
Python中序列的修改、散列与切片详解
Aug 27 Python
python实现换位加密算法的示例
Oct 14 Python
Django管理员账号和密码忘记的完美解决方法
Dec 06 Python
Python基于Logistic回归建模计算某银行在降低贷款拖欠率的数据示例
Jan 23 Python
python实现可逆简单的加密算法
Mar 22 Python
浅谈keras中的目标函数和优化函数MSE用法
Jun 10 Python
Python 中如何写注释
Aug 28 Python
详解MindSpore自定义模型损失函数
Jun 30 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
缅甸的咖啡简史
2021/03/04 咖啡文化
PHP 命令行参数详解及应用
2011/05/18 PHP
解决phpcms更换javascript的幻灯片代码调用图片问题
2014/12/26 PHP
阿里云PHP SMS短信服务验证码发送方法
2017/07/11 PHP
thinkPHP通用控制器实现方法示例
2017/11/23 PHP
PHP实现基于3DES算法加密解密字符串示例
2018/08/24 PHP
PHP下用Swoole实现Actor并发模型的方法
2019/06/12 PHP
php实现的证件照换底色功能示例【人像抠图/换背景图】
2020/05/29 PHP
浅析jQuery的链式调用之each函数
2010/12/03 Javascript
以JSON形式将JS中Array对象数组传至后台的方法
2014/01/06 Javascript
让JavaScript中setTimeout支持链式操作的方法
2015/06/19 Javascript
分享我的jquery实现下拉菜单心的
2015/11/29 Javascript
基于javascript实现文字无缝滚动效果
2016/03/22 Javascript
react-router JS 控制路由跳转实例
2017/06/15 Javascript
解决vue打包之后静态资源图片失效的问题
2018/02/21 Javascript
vue element-ui 绑定@keyup事件无效的解决方法
2018/03/09 Javascript
jQuery实现的简单日历组件定义与用法示例
2018/12/24 jQuery
vue-cli3 从搭建到优化的详细步骤
2019/01/20 Javascript
基于JS实现父组件的请求服务过程解析
2019/10/14 Javascript
vue element-ui中table合计指定列求和实例
2020/11/02 Javascript
Python实现Linux下守护进程的编写方法
2014/08/22 Python
python通过colorama模块在控制台输出彩色文字的方法
2015/03/19 Python
python中MethodType方法介绍与使用示例
2017/08/03 Python
python实现读Excel写入.txt的方法
2018/04/29 Python
python下PyGame的下载与安装过程及遇到问题
2019/08/04 Python
Python3使用PySynth制作音乐的方法
2019/09/09 Python
Python爬虫爬取电影票房数据及图表展示操作示例
2020/03/27 Python
tensorflow2.0的函数签名与图结构(推荐)
2020/04/28 Python
浅谈Selenium+Webdriver 常用的元素定位方式
2021/01/13 Python
FOREO斐珞尔官方旗舰店:LUNA露娜洁面仪
2018/03/11 全球购物
美国地毯购买网站:Rugs USA
2019/02/23 全球购物
股东出资协议书
2016/03/21 职场文书
如何书写你的职业生涯规划书?
2019/06/27 职场文书
导游词之新疆尼雅遗址
2019/10/16 职场文书
Python基础之变量的相关知识总结
2021/06/23 Python
Python基础 括号()[]{}的详解
2021/11/07 Python