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下Fabric的简单部署方法
Jul 14 Python
Pythont特殊语法filter,map,reduce,apply使用方法
Feb 27 Python
python 打印出所有的对象/模块的属性(实例代码)
Sep 11 Python
Python给定一个句子倒序输出单词以及字母的方法
Dec 20 Python
numpy数组做图片拼接的实现(concatenate、vstack、hstack)
Nov 08 Python
pandas中ix的使用详细讲解
Mar 09 Python
在Windows上安装和配置 Jupyter Lab 作为桌面级应用程序教程
Apr 22 Python
TensorFlow使用Graph的基本操作的实现
Apr 22 Python
Django ORM判断查询结果是否为空,判断django中的orm为空实例
Jul 09 Python
通过实例了解python__slots__使用方法
Sep 14 Python
python 用opencv实现霍夫线变换
Nov 27 Python
python爬虫基础之urllib的使用
Dec 31 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队列用法实例
2014/11/05 PHP
PHP使用GETDATE获取当前日期时间作为一个关联数组的方法
2015/03/19 PHP
WordPress主题中添加文章列表页页码导航的PHP代码实例
2015/12/22 PHP
php常用字符函数实例小结
2016/12/29 PHP
JavaScript 空位补零实现代码
2010/02/26 Javascript
jquery获取ASP.NET服务器端控件dropdownlist和radiobuttonlist生成客户端HTML标签后的value和text值
2010/06/28 Javascript
Javascript 倒计时源代码.(时.分.秒) 详细注释版
2011/05/09 Javascript
关于JavaScript中string 的replace
2013/04/12 Javascript
用客户端js实现带省略号的分页
2013/04/27 Javascript
js清空表单数据的两种方式(遍历+reset)
2014/07/18 Javascript
jQuery中contents()方法用法实例
2015/01/08 Javascript
js实现点击图片将图片地址复制到粘贴板的方法
2015/02/16 Javascript
js中遍历对象的属性和值的方法
2016/07/27 Javascript
JQueryEasyUI之DataGrid数据显示
2016/11/23 Javascript
在网页中插入百度地图的步骤详解
2016/12/02 Javascript
详解angularJs中关于ng-class的三种使用方式说明
2017/06/02 Javascript
jquery拖动改变div大小
2017/07/04 jQuery
Jquery 动态添加元素并添加点击事件实现过程解析
2019/10/12 jQuery
详解Vscode中使用Eslint终极配置大全
2019/11/08 Javascript
java遇到微信小程序 "支付验证签名失败" 问题解决
2019/12/22 Javascript
JS实现扫码枪扫描二维码功能
2020/01/03 Javascript
小程序实现图片移动缩放效果
2020/05/26 Javascript
[43:43]完美世界DOTA2联赛PWL S2 FTD.C vs Rebirth 第一场 11.22
2020/11/24 DOTA
Python中的多重装饰器
2015/04/11 Python
在Python上基于Markov链生成伪随机文本的教程
2015/04/17 Python
Python实现并行抓取整站40万条房价数据(可更换抓取城市)
2016/12/14 Python
Python字符串格式化%s%d%f详解
2018/02/02 Python
Python3.6简单的操作Mysql数据库的三个实例
2018/10/17 Python
python实现京东订单推送到测试环境,提供便利操作示例
2019/08/09 Python
Python定时任务框架APScheduler原理及常用代码
2020/10/05 Python
大二自我鉴定
2014/01/31 职场文书
经销商订货会主持词
2014/03/27 职场文书
中华魂演讲稿
2014/05/13 职场文书
大专学生求职自荐信
2014/07/06 职场文书
亮剑精神观后感
2015/06/05 职场文书
创业计划书详解
2019/07/19 职场文书