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实现稀疏矩阵示例代码
Jun 09 Python
Python-OpenCV基本操作方法详解
Apr 02 Python
对python 矩阵转置transpose的实例讲解
Apr 17 Python
对tf.reduce_sum tensorflow维度上的操作详解
Jul 26 Python
使用Python制作自动推送微信消息提醒的备忘录功能
Sep 06 Python
Pandas DataFrame数据的更改、插入新增的列和行的方法
Jun 25 Python
Python日志syslog使用原理详解
Feb 18 Python
python+selenium+PhantomJS抓取网页动态加载内容
Feb 25 Python
python opencv 实现读取、显示、写入图像的方法
Jun 08 Python
Python在字符串中处理html和xml的方法
Jul 31 Python
python进度条显示之tqmd模块
Aug 22 Python
matplotlib相关系统目录获取方式小结
Feb 03 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
BBS(php & mysql)完整版(一)
2006/10/09 PHP
windows下zendframework项目环境搭建(通过命令行配置)
2012/12/06 PHP
php cli换行示例
2014/04/22 PHP
PHP判断用户是否已经登录(跳转到不同页面或者执行不同动作)
2016/09/22 PHP
使用laravel和ECharts实现折线图效果的例子
2019/10/09 PHP
一个判断email合法性的函数[非正则]
2008/12/09 Javascript
setTimeout 不断吐食CPU的问题分析
2009/04/01 Javascript
Jquery上传插件 uploadify v3.1使用说明
2012/06/18 Javascript
往光标所在位置插入值的js代码
2013/09/22 Javascript
jquery对单选框,多选框,文本框等常见操作小结
2014/01/08 Javascript
jQuery制作简洁的图片轮播效果
2015/04/03 Javascript
jQuery实现鼠标经过弹出提示信息的地图热点效果
2015/08/07 Javascript
Javascript仿新浪游戏频道鼠标悬停显示子菜单效果
2015/08/21 Javascript
基于Bootstrap+jQuery.validate实现表单验证
2016/05/30 Javascript
全面介绍javascript实用技巧及单竖杠
2016/07/18 Javascript
vue.js通过自定义指令实现数据拉取更新的实现方法
2016/10/18 Javascript
nodejs中使用HTTP分块响应和定时器示例代码
2017/03/19 NodeJs
React服务端渲染(总结)
2017/07/01 Javascript
JavaScript模块模式实例详解
2017/10/25 Javascript
解决v-for中使用v-if或者v-bind:class失效的问题
2018/09/25 Javascript
JS实现点击li标签弹出对应的索引功能【案例】
2019/02/18 Javascript
swiper4实现移动端导航栏tab滑动切换
2020/10/16 Javascript
用python实现面向对像的ASP程序实例
2014/11/10 Python
python实现查询苹果手机维修进度
2015/03/16 Python
Python实现队列的方法
2015/05/26 Python
对Python中plt的画图函数详解
2018/11/07 Python
把pandas转换int型为str型的方法
2019/01/29 Python
GitHub 热门:Python 算法大全,Star 超过 2 万
2019/04/29 Python
对python中url参数编码与解码的实例详解
2019/07/25 Python
pycharm 激活码及使用方式的详细教程
2020/05/12 Python
英语专业学生的自我评价
2013/12/30 职场文书
反四风个人对照检查材料
2014/09/26 职场文书
交通事故协议书范本
2014/11/18 职场文书
面试通知邮件
2015/04/20 职场文书
vue引入Excel表格插件的方法
2021/04/28 Vue.js
Tomcat starup.bat 脚本实现开机自启动
2022/04/20 Servers