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中with语句的用法
Apr 15 Python
浅谈python内置变量-reversed(seq)
Jun 21 Python
Python3 中把txt数据文件读入到矩阵中的方法
Apr 27 Python
详解django的serializer序列化model几种方法
Oct 16 Python
详解Python 正则表达式模块
Nov 05 Python
python中时间转换datetime和pd.to_datetime详析
Aug 11 Python
pandas 对group进行聚合的例子
Dec 27 Python
在主流系统之上安装Pygame的方法
May 20 Python
python rolling regression. 使用 Python 实现滚动回归操作
Jun 08 Python
python 基于selenium实现鼠标拖拽功能
Dec 24 Python
使用numpngw和matplotlib生成png动画的示例代码
Jan 24 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
在apache下限制每个虚拟主机的并发数!!!!
2006/10/09 PHP
从零开始学YII2框架(四)扩展插件yii2-kartikgii
2014/08/20 PHP
php生成唯一的订单函数分享
2015/02/02 PHP
Yii rules常用规则示例
2016/03/15 PHP
详解PHP的Yii框架中的Controller控制器
2016/03/29 PHP
PHP实现验证码校验功能
2017/11/16 PHP
PHP多线程模拟实现秒杀抢单
2018/02/07 PHP
PHP实现的敏感词过滤方法示例
2019/03/06 PHP
PHP实现随机发放扑克牌
2020/04/21 PHP
通用于ie和firefox的函数 GetCurrentStyle (obj, prop)
2006/12/27 Javascript
基于jQuery的图片大小自动适应实现代码
2010/11/17 Javascript
一个挺有意思的Javascript小问题说明
2011/09/26 Javascript
jQuery的$.proxy()应用示例介绍
2014/04/03 Javascript
初识Node.js
2015/03/20 Javascript
js+canvas绘制五角星的方法
2016/01/28 Javascript
javascript中call apply 与 bind方法详解
2016/03/10 Javascript
JS、jQuery中select的用法详解
2016/04/21 Javascript
Bootstrap网格系统详解
2016/04/26 Javascript
js 中获取制定的cook信息实现方法
2016/11/19 Javascript
巧用数组制作图片切换js代码
2016/11/29 Javascript
浅谈Vue数据响应思路之数组
2018/11/06 Javascript
vue+webpack中配置ESLint
2018/11/07 Javascript
JavaScript中BOM对象原理与用法分析
2019/07/09 Javascript
微信小程序转化为uni-app项目的方法示例
2020/05/22 Javascript
在vue项目中封装echarts的步骤
2020/12/25 Vue.js
[02:54]DOTA2英雄基础教程 撼地者
2014/01/14 DOTA
Python3实现汉语转换为汉语拼音
2019/07/08 Python
使用Tensorboard工具查看Loss损失率
2020/02/15 Python
Html5 实现微信分享及自定义内容的流程
2019/08/20 HTML / CSS
Roxy美国官网:澳大利亚冲浪、滑雪健身品牌
2016/07/30 全球购物
去加拿大的旅行和假期:Canadian Affair
2016/10/25 全球购物
五年级英语教学反思
2014/01/31 职场文书
小学教师先进事迹材料
2014/12/15 职场文书
搞笑Gif:这么白这么长的腿像极了一楼的女朋友
2022/03/21 杂记
python中的getter与setter你了解吗
2022/03/24 Python
使用Nginx的访问日志统计PV与UV
2022/05/06 Servers