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条件和循环的使用方法
Nov 01 Python
Python中分数的相关使用教程
Mar 30 Python
介绍Python的@property装饰器的用法
Apr 28 Python
shelve  用来持久化任意的Python对象实例代码
Oct 12 Python
python数据类型判断type与isinstance的区别实例解析
Oct 31 Python
对Python3 序列解包详解
Feb 16 Python
通过pycharm使用git的步骤(图文详解)
Jun 13 Python
Python异常模块traceback用法实例分析
Oct 22 Python
python如何实现不可变字典inmutabledict
Jan 08 Python
python读取csv文件指定行的2种方法详解
Feb 13 Python
Keras中 ImageDataGenerator函数的参数用法
Jul 03 Python
Python爬虫之Selenium实现关闭浏览器
Dec 04 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中执行系统外部命令
2006/10/09 PHP
PHP连接Nginx服务器并解析Nginx日志的方法
2015/08/16 PHP
Yii框架连接mongodb数据库的代码
2016/07/27 PHP
PHP数组内存利用率低和弱类型详细解读
2017/08/10 PHP
PHP实现微信小程序用户授权的工具类示例
2019/03/05 PHP
ExtJS 2.0实用简明教程 之获得ExtJS
2009/04/29 Javascript
json-lib出现There is a cycle in the hierarchy解决办法
2010/02/24 Javascript
尝试在让script的type属性等于text/html
2013/01/15 Javascript
jQuery中:first选择器用法实例
2014/12/30 Javascript
nodejs简单实现中英文翻译
2015/05/04 NodeJs
浅析创建javascript对象的方法
2016/05/13 Javascript
jQuery中ScrollTo用法示例
2016/09/04 Javascript
jQuery查找节点并获取节点属性的方法
2016/09/09 Javascript
基于Swiper实现移动端页面图片轮播效果
2017/12/28 Javascript
Vue引用第三方datepicker插件无法监听datepicker输入框的值的解决
2018/01/27 Javascript
JavaScrip如果基于url实现图片下载
2020/07/03 Javascript
js实现盒子拖拽动画效果
2020/08/09 Javascript
原生js实现简单轮播图
2020/10/26 Javascript
[37:23]DOTA2上海特级锦标赛主赛事日 - 3 胜者组第二轮#2Secret VS EG第二局
2016/03/04 DOTA
[03:55]DOTA2完美大师赛选手传记——LFY.MONET
2017/11/18 DOTA
[57:09]DOTA2-DPC中国联赛 正赛 Phoenix vs Dynasty BO3 第一场 1月26日
2021/03/11 DOTA
跟老齐学Python之不要红头文件(2)
2014/09/28 Python
基于python编写的微博应用
2014/10/17 Python
Django添加KindEditor富文本编辑器的使用
2018/10/24 Python
Python二维数组实现求出3*3矩阵对角线元素的和示例
2019/11/29 Python
Python 格式化打印json数据方法(展开状态)
2020/02/27 Python
jupyter notebook 多行输出实例
2020/04/09 Python
python实现视频压缩功能
2020/12/18 Python
详解HTML5通讯录获取指定多个人的信息
2016/12/20 HTML / CSS
The North Face北面法国官网:美国著名户外品牌
2019/11/01 全球购物
面试感谢信范文
2015/01/22 职场文书
经营场所使用证明
2015/06/19 职场文书
2015年治庸问责工作总结
2015/07/27 职场文书
2016春季校长开学典礼致辞
2015/11/26 职场文书
南阳市白酒市场的调查报告
2019/11/08 职场文书
tomcat下部署jenkins的方法
2022/05/06 Servers