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提取html文件中的特定数据的实现代码
Mar 24 Python
使用Python中的cookielib模拟登录网站
Apr 09 Python
使用python实现省市三级菜单效果
Jan 20 Python
Python黑魔法Descriptor描述符的实例解析
Jun 02 Python
JPype实现在python中调用JAVA的实例
Jul 19 Python
教你用一行Python代码实现并行任务(附代码)
Feb 02 Python
Python中字符串List按照长度排序
Jul 01 Python
浅谈Python_Openpyxl使用(最全总结)
Sep 05 Python
Python使用matplotlib绘制三维参数曲线操作示例
Sep 10 Python
Python 去除字符串中指定字符串
Mar 05 Python
jupyter修改文件名方式(TensorFlow)
Apr 21 Python
python 下划线的多种应用场景总结
May 12 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 无线电
体育彩票排列三组选三算法分享
2014/03/07 PHP
javascript mouseover、mouseout停止事件冒泡的解决方案
2009/04/07 Javascript
JavaScript prototype属性使用说明
2010/05/13 Javascript
jQuery随便控制任意div隐藏的方法
2013/06/28 Javascript
jQuery动态添加删除select项(实现代码)
2013/09/03 Javascript
javascript实现数字倒计时特效
2016/03/30 Javascript
Angular 4依赖注入学习教程之Injectable装饰器(六)
2017/06/04 Javascript
基于Cookie常用操作以及属性介绍
2017/09/07 Javascript
bootstrap-Treeview实现级联勾选
2017/11/23 Javascript
微信小程序中使用ECharts 异步加载数据的方法
2018/06/27 Javascript
vue单文件组件lint error自动fix与styleLint报错自动fix详解
2019/01/08 Javascript
element-ui带输入建议的input框踩坑(输入建议空白以及会闪出上一次的输入建议问题)
2019/01/15 Javascript
微信小程序实现顶部导航特效
2019/01/28 Javascript
vue中多路由表头吸顶实现的几种布局方式
2019/04/12 Javascript
js 将线性数据转为树形的示例代码
2019/05/28 Javascript
vue App.vue中的公共组件改变值触发其他组件或.vue页面监听
2019/05/31 Javascript
Vue实现商品详情页的评价列表功能
2019/09/04 Javascript
js中复选框的取值及赋值示例详解
2020/10/18 Javascript
[41:17]完美世界DOTA2联赛PWL S3 access vs CPG 第二场 12.13
2020/12/17 DOTA
将Python的Django框架与认证系统整合的方法
2015/07/24 Python
django rest framework之请求与响应(详解)
2017/11/06 Python
Python中断多重循环的思路总结
2019/10/04 Python
详解如何用python实现一个简单下载器的服务端和客户端
2019/10/28 Python
pandas 像SQL一样使用WHERE IN查询条件说明
2020/06/05 Python
HTML5中的websocket实现直播功能
2018/05/21 HTML / CSS
菲律宾酒店预订网站:Hotels.com菲律宾
2017/07/12 全球购物
合作协议书怎么写
2014/04/18 职场文书
2014物价局民主生活会对照检查材料思想汇报
2014/09/24 职场文书
正风肃纪查摆剖析材料
2014/10/10 职场文书
2014年学生会部门工作总结
2014/11/07 职场文书
催款律师函范文
2015/05/27 职场文书
vue引入Excel表格插件的方法
2021/04/28 Vue.js
JavaScript实现简单图片切换
2021/04/29 Javascript
mysql查找连续出现n次以上的数字
2022/05/11 MySQL
python自动获取微信公众号最新文章的实现代码
2022/07/15 Python