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的类中动态添加属性与生成对象
Sep 17 Python
Python用UUID库生成唯一ID的方法示例
Dec 15 Python
python数据结构之列表和元组的详解
Sep 23 Python
python绘制立方体的方法
Jul 02 Python
python使用Matplotlib绘制分段函数
Sep 25 Python
Python自动发送邮件的方法实例总结
Dec 08 Python
Python处理session的方法整理
Aug 29 Python
Python帮你识破双11的套路
Nov 11 Python
python opencv 实现对图像边缘扩充
Jan 19 Python
keras读取h5文件load_weights、load代码操作
Jun 12 Python
python函数超时自动退出的实操方法
Dec 28 Python
python异步的ASGI与Fast Api实现
Jul 16 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
第六节--访问属性和方法
2006/11/16 PHP
PHP得到某段时间区间的时间戳 php定时任务
2012/04/12 PHP
PHP实现将几张照片拼接到一起的合成图片功能【便于整体打印输出】
2017/11/14 PHP
Laravel框架模板继承操作示例
2018/06/11 PHP
JavaScript操作XML实例代码(获取新闻标题并分页,并分页)
2010/05/25 Javascript
jQuery Ajax请求状态管理器打包
2012/05/03 Javascript
js使浏览器窗口最大化实现代码(适用于IE)
2013/08/07 Javascript
js实现连个数字相加而不是拼接的方法
2014/02/23 Javascript
js的Boolean对象初始值示例
2014/03/04 Javascript
AngularJS模块详解及示例代码
2016/08/17 Javascript
AngularJS监听路由的变化示例代码
2016/09/23 Javascript
为jQuery-easyui的tab组件添加右键菜单功能的简单实例
2016/10/10 Javascript
微信小程序  Mustache语法详细介绍
2016/10/27 Javascript
详解升级react-router 4 踩坑指南
2017/08/14 Javascript
Vue formData实现图片上传
2019/08/20 Javascript
微信小程序中限制激励式视频广告位显示次数(实现思路)
2019/12/06 Javascript
Vue项目中使用mock.js的完整步骤
2021/01/12 Vue.js
Java多线程编程中ThreadLocal类的用法及深入
2016/06/21 Python
恢复百度云盘本地误删的文件脚本(简单方法)
2017/10/21 Python
python基于SMTP协议发送邮件
2019/05/31 Python
python中sort和sorted排序的实例方法
2019/08/26 Python
python 爬虫百度地图的信息界面的实现方法
2019/10/27 Python
django框架使用views.py的函数对表进行增删改查内容操作详解【models.py中表的创建、views.py中函数的使用,基于对象的跨表查询】
2019/12/12 Python
深入探究HTML5的History API
2015/07/09 HTML / CSS
英国豪华装饰照明品牌的在线零售商:Inspyer Lighting
2019/12/10 全球购物
Java基础类库面试题
2013/09/04 面试题
市场营销专业毕业生自荐信
2013/11/02 职场文书
住房公积金接收函
2014/01/09 职场文书
家长会邀请书
2014/01/25 职场文书
2014年三八妇女节活动方案
2014/02/28 职场文书
银行求职信怎么写
2014/05/26 职场文书
金融系应届毕业生求职信
2014/05/26 职场文书
学习型班组申报材料
2014/05/31 职场文书
2015年保洁工作总结范文
2015/04/28 职场文书
mysql对于模糊查询like的一些汇总
2021/05/09 MySQL
Java Shutdown Hook场景使用及源码分析
2021/06/15 Java/Android