1 . 在Django中使用身份认证系统

Django的身份认证系统实际上是一个app,该app叫做django.contrib.auth,它在django contrib模块下

使用时只需要在setting.py文件的INSTALLED_APPS中添加:'django.contrib.auth' 即可

身份认证系统包括以下内容:

  • 用户
  • 权限:标志指定用户是否可以执行某项任务。
  • 组:向多个用户应用标签和权限的通用方法。
  • 可配置的密码散列系统
  • 用于登录用户或限制内容的表单和视图工具
  • 可插拔的后端系统

该身份认证系统包含密码强度检查、登陆限制、第三方身份验证、对象级权限设置

2. 添加与Django身份认证系统相关联的app

注意:使用身份认证系统时,一定要添加django.contrib.contenttypes这个app

这个app的叫做内容类型系统,它将允许身份认证系统与我们创建的模型相关联

也就是说身份认证系统与我们创建的模型需要通过内容类型系统进行处理

3. 添加与身份认证系统相关联的中间件

添加完这两个app后,还要在中间件中添加相关内容,即在setting.py文件的MIDDLEWARE中添加以下内容:

  • SessionMiddleware:session中间件,用来管理请求会话
  • AuthenticationMiddleware:身份验证中间件,用来使用户和请求相关联

总的来说身份认证系统使用了2个app,2个中间件

然后执行python manage.py migrate命令,数据库就会创建权限、用户、组相关的表结构

此时,我们可以执行 python manage.py createsuperuser 命令创建超级用户,然后启动django项目

访问:http://127.0.0.1:8000/admin/ 这个网址,对用户进行管理

注意:后台管理模块依赖于 django.contrib.admin 这个app

4. 身份认证系统中的密码加密

django默认使用PBKDF2进行密码存储,该密码机制非常安全,如果想要使用其他密码机制,则要在setting文件中修改即可,

以下是django提供的密码机制:

['django.contrib.auth.hashers.PBKDF2PasswordHasher','django.contrib.auth.hashers.PBKDF2SHA1PasswordHasher','django.contrib.auth.hashers.Argon2PasswordHasher','django.contrib.auth.hashers.BCryptSHA256PasswordHasher','django.contrib.auth.hashers.BCryptPasswordHasher','django.contrib.auth.hashers.SHA1PasswordHasher','django.contrib.auth.hashers.MD5PasswordHasher','django.contrib.auth.hashers.UnsaltedSHA1PasswordHasher','django.contrib.auth.hashers.UnsaltedMD5PasswordHasher','django.contrib.auth.hashers.CryptPasswordHasher',
]

对应的python算法是:

pbkdf2_sha256
pbkdf2_sha1
argon2
bcrypt_sha256
bcrypt
sha1
md5
unsalted_sha1
unsalted_md5
crypt

下面的代码是修改默认的密码机制,首先要在setting.py中添加下面的内容,

然后修改PASSWORD_HASHERS数组中下标为【0】的的数据,下标为0的指的就是密码保存时的加密算法:

PASSWORD_HASHERS = ['django.contrib.auth.hashers.PBKDF2PasswordHasher','django.contrib.auth.hashers.PBKDF2SHA1PasswordHasher','django.contrib.auth.hashers.Argon2PasswordHasher','django.contrib.auth.hashers.BCryptSHA256PasswordHasher',
]

将上述的PBKDF2修改为MD5

PASSWORD_HASHERS = ['django.contrib.auth.hashers.MD5PasswordHasher','django.contrib.auth.hashers.PBKDF2SHA1PasswordHasher','django.contrib.auth.hashers.Argon2PasswordHasher','django.contrib.auth.hashers.BCryptSHA256PasswordHasher',
]

这里要说明一下DJango加密数据后的存储规则,其中$是分隔符:

<algorithm>$<iterations>$<salt>$<hash>
  • 第一个成员是散列算法,指的是md5,pbkdf2之类
  • 第二个成员是迭代次数(工作因子),跟君算法不同可以是字符串或数字
  • 第三个成员是随机盐
  • 第四个是密码哈希

两个不同的算法生成的结果如下,前两条是用pbkdf2加密的,后两条是md5:

启动Django,使用admin后台管理系统,添加用户,就能查看该用户的加密后的密码

Django会按照你在setting中的配置生成指定规则的密码,上面已说过

当然,django的密码加密不仅于此,还能将旧系统中的老密码重新进行加密升级,这个升级过程称之为包装

即将已有用户的以sha1加密的密码包装升级为PBKDF2加密的密码,这个升级过程和用户的登录无关

这一块用的人较少,仅说明一下,想看具体内容请访问官方文档:Django官方文档

5. 身份认证系统中的用户密码修改

密码修改有两种,一种是不需要原密码进行修改,一种是需要原密码进行修改

不需要原密码进行修改有下面三种方式:

  • admin后台管理系统
  • python manage.py changepassword 修改
  • 通过自定义视图修改

 admin修改如下图:

 命令行修改方式如下:

 在Views.py视图中修改方式如下:

def mysql(request):template = loader.get_template('app_Mysql/table.html')context = {'latest_question_list': {'xxx': 123},}from django.contrib.auth.models import Useru = User.objects.get(username='zhangsan')u.set_password('zhangsan66666')u.save()

需要身份验证修改密码的方式如下:

Django的身份验证除了可以使用自带的身份验证,也可以使用自定义的身份验证

下面是使用自带的身份验证:

def mysql(request):template = loader.get_template('app_Mysql/table.html')context = {'latest_question_list': {'xxx': 123},}# from django.contrib.auth.models import User# u = User.objects.get(username='zhangsan')# u.set_password('zhangsan66666')# u.save()from django.contrib.auth import authenticateuser = authenticate(username='zhangsan', password='zhangsan66666')if user is not None:print('账户、密码输入正确')else:print('账户、密码输入不正确')return HttpResponse(template.render(context,request))

authenticate会根据获得的用户密码,去【检查】【配置的】【身份认证后端】,并返回一个是否有效的User用户(,假如配置了多个认证后端的话,检查过程会挨个检查认证后端,)

如果无效则返回None,有效则返回该用户

这里说明一下什么是身份认证后端:

身份认证后端:用于与【用户模型Model】相关联的【存储用户名和密码】的【一组服务】,称之为验证后端

即这个后端和用户模型挂钩,且为这个用户模型提供了相关验证服务

既然是Django提供的服务,那么我们就可以对这个服务进行定制、修改、替换

例如:公司已经存在一个LDAP,可以为每个员工存储用户名和密码,如果用户在LDAP和基于Django的应用程序中有单独的帐户,那么网络管理员和用户自己都会很麻烦。(用户登录时django会先验证该用户,然后再去ladp验证)

上面的情况就需要修改Django默认的认证后端,首先要在setting.py中添加下面的内容:

AUTHENTICATION_BACKENDS =['django.contrib.auth.backends.ModelBackend'
]

然后对其进行替换,替换为我们自已定义的身份验证类。

也可以在这个数组中加入我们自定义的身份认证后端,加入后,程序会按照下面的方式进行,

先到默认的ModelBackend验证,然后再到我们加入的验证后端中验证,知道即可,不再赘述。

默认的验证类包含了用户身份验证、用户组、用户权限、权限组等,还是很全的

from __future__ import unicode_literalsfrom django.contrib.auth import get_user_model
from django.contrib.auth.models import PermissionUserModel = get_user_model()class ModelBackend(object):"""Authenticates against settings.AUTH_USER_MODEL."""def authenticate(self, request, username=None, password=None, **kwargs):if username is None:username = kwargs.get(UserModel.USERNAME_FIELD)try:user = UserModel._default_manager.get_by_natural_key(username)except UserModel.DoesNotExist:# Run the default password hasher once to reduce the timing# difference between an existing and a non-existing user (#20760).UserModel().set_password(password)else:if user.check_password(password) and self.user_can_authenticate(user):return userdef user_can_authenticate(self, user):"""Reject users with is_active=False. Custom user models that don't havethat attribute are allowed."""is_active = getattr(user, 'is_active', None)return is_active or is_active is Nonedef _get_user_permissions(self, user_obj):return user_obj.user_permissions.all()def _get_group_permissions(self, user_obj):user_groups_field = get_user_model()._meta.get_field('groups')user_groups_query = 'group__%s' % user_groups_field.related_query_name()return Permission.objects.filter(**{user_groups_query: user_obj})def _get_permissions(self, user_obj, obj, from_name):"""Returns the permissions of `user_obj` from `from_name`. `from_name` canbe either "group" or "user" to return permissions from`_get_group_permissions` or `_get_user_permissions` respectively."""if not user_obj.is_active or user_obj.is_anonymous or obj is not None:return set()perm_cache_name = '_%s_perm_cache' % from_nameif not hasattr(user_obj, perm_cache_name):if user_obj.is_superuser:perms = Permission.objects.all()else:perms = getattr(self, '_get_%s_permissions' % from_name)(user_obj)perms = perms.values_list('content_type__app_label', 'codename').order_by()setattr(user_obj, perm_cache_name, set("%s.%s" % (ct, name) for ct, name in perms))return getattr(user_obj, perm_cache_name)def get_user_permissions(self, user_obj, obj=None):"""Returns a set of permission strings the user `user_obj` has from their`user_permissions`."""return self._get_permissions(user_obj, obj, 'user')def get_group_permissions(self, user_obj, obj=None):"""Returns a set of permission strings the user `user_obj` has from thegroups they belong."""return self._get_permissions(user_obj, obj, 'group')def get_all_permissions(self, user_obj, obj=None):if not user_obj.is_active or user_obj.is_anonymous or obj is not None:return set()if not hasattr(user_obj, '_perm_cache'):user_obj._perm_cache = self.get_user_permissions(user_obj)user_obj._perm_cache.update(self.get_group_permissions(user_obj))return user_obj._perm_cachedef has_perm(self, user_obj, perm, obj=None):if not user_obj.is_active:return Falsereturn perm in self.get_all_permissions(user_obj, obj)def has_module_perms(self, user_obj, app_label):"""Returns True if user_obj has any permissions in the given app_label."""if not user_obj.is_active:return Falsefor perm in self.get_all_permissions(user_obj):if perm[:perm.index('.')] == app_label:return Truereturn Falsedef get_user(self, user_id):try:user = UserModel._default_manager.get(pk=user_id)except UserModel.DoesNotExist:return Nonereturn user if self.user_can_authenticate(user) else Noneclass AllowAllUsersModelBackend(ModelBackend):def user_can_authenticate(self, user):return Trueclass RemoteUserBackend(ModelBackend):"""This backend is to be used in conjunction with the ``RemoteUserMiddleware``found in the middleware module of this package, and is used when the serveris handling authentication outside of Django.By default, the ``authenticate`` method creates ``User`` objects forusernames that don't already exist in the database.  Subclasses can disablethis behavior by setting the ``create_unknown_user`` attribute to``False``."""# Create a User object if not already in the database?create_unknown_user = Truedef authenticate(self, request, remote_user):"""The username passed as ``remote_user`` is considered trusted.  Thismethod simply returns the ``User`` object with the given username,creating a new ``User`` object if ``create_unknown_user`` is ``True``.Returns None if ``create_unknown_user`` is ``False`` and a ``User``object with the given username is not found in the database."""if not remote_user:returnuser = Noneusername = self.clean_username(remote_user)# Note that this could be accomplished in one try-except clause, but# instead we use get_or_create when creating unknown users since it has# built-in safeguards for multiple threads.if self.create_unknown_user:user, created = UserModel._default_manager.get_or_create(**{UserModel.USERNAME_FIELD: username})if created:user = self.configure_user(user)else:try:user = UserModel._default_manager.get_by_natural_key(username)except UserModel.DoesNotExist:passreturn user if self.user_can_authenticate(user) else Nonedef clean_username(self, username):"""Performs any cleaning on the "username" prior to using it to get orcreate the user object.  Returns the cleaned username.By default, returns the username unchanged."""return usernamedef configure_user(self, user):"""Configures a user after creation and returns the updated user.By default, returns the user unmodified."""return userclass AllowAllUsersRemoteUserBackend(RemoteUserBackend):def user_can_authenticate(self, user):return True

了解更相信的内容,看官方文档:官方文档---身份认证后端

6. 用户的权限缓存

Django默认的ModelBackend会在用户请求登陆时获取该用户的相应权限,然后进行缓存,该缓存直至用户会话结束,否则不会刷新。

如果在页面上对该用户的权限做出了修改并且要求该用户新修改的权限立即生效,那么就需要重新获取该用户的相关权限

下面是获取用户权限的方法例子:

from django.contrib.auth.models import Permission, User
from django.contrib.contenttypes.models import ContentType
from django.shortcuts import get_object_or_404from myapp.models import BlogPostdef user_gains_perms(request, user_id):user = get_object_or_404(User, pk=user_id)# any permission check will cache the current set of permissionsuser.has_perm('myapp.change_blogpost')content_type = ContentType.objects.get_for_model(BlogPost)permission = Permission.objects.get(codename='change_blogpost',content_type=content_type,)user.user_permissions.add(permission)# Checking the cached permission setuser.has_perm('myapp.change_blogpost')  # False# Request new instance of User# Be aware that user.refresh_from_db() won't clear the cache.user = get_object_or_404(User, pk=user_id)# Permission cache is repopulated from the databaseuser.has_perm('myapp.change_blogpost')  # True...

7. 用户退出操作

添加相应的url,然后添加对应的views中添加以下内容即可:

#创建自定义的View,用来封装返回结果使用
class ResponseResult_View(View):def __init__(self):self.code = 201self.message = '操作成功'self.data = Nonedef get_result(self):return {'code': self.code, 'message': self.message, 'data': self.data}# 用户退出
class User_logout(ResponseResult_View):@logging(level='INFO')def get(self, request):logout(request)return render(request, "app_User/login.html")

8. 未验证用户的重定向操作

重定向使用装饰器能够轻松解决指定视图用户访问时的验证问题

下面是django的默认装饰器login_required,该装饰器可以无参,也可以有参:

无参情况,在setting设置跳转:

#无参情况#setting文件内容,需要指定LOGIN_URL
未登录,重定向页面
LOGIN_URL = '/user/login'#主页
@login_required
def User_main(request):return render(request, 'app_User/main.html',)

有参情况,直接在装饰器参数中指定跳转:

@login_required(login_url='/user/login')
def User_main(request):return render(request, 'app_User/main.html',)

注意:user/login要配置在app的urls中,如下图:

from django.conf.urls import urlfrom app_User import viewsurlpatterns = [url(r'^main$', views.User_main, name='main'),url(r'^login$', views.User_login.as_view(), name='login'),url(r'^logout$', views.User_logout.as_view(), name='logout'),]

至于登录模块的验证的更多方法,请参考:官方文档authenticate

Django的身份认证系统相关推荐

  1. django(权限、认证)系统——用户Login,Logout

    django(权限.认证)系统--用户Login,Logout 上面两篇文章,讲述的Django的Authentication系统的核心模型对象User API和相关的使用,本文继续深入,讨论如何在W ...

  2. 生物识别最新进展:动态密码语音无监督身份认证系统通过科技成果鉴定

    近日,由中国电子学会主持召开的"基于动态密码语音的无监督身份认证系统"科技成果鉴定会在清华大学举办,AI科技大本营受邀出席. 该成果由清华大学.北京得意音通技术有限责任公司共同完成 ...

  3. 架构师之路 — API 经济 — 身份认证系统

    目录 文章目录 目录 身份认证系统 Cookie Auth Token Auth AK/SK Auth AK/SK Auth 实现原理 Step 1:获取 AK/SK Step 2:构造一个 HTTP ...

  4. django(权限、认证)系统—— 基于Authentication backends定制

    django(权限.认证)系统-- 基于Authentication backends定制 在这篇文章中,我们进行最后关于DjangoPermission系统的探讨,来谈谈关于Permission系统 ...

  5. Django默认用户认证系统和用户模型类

    Django默认用户认证系统和用户模型类 1.Django默认用户认证系统 Django自带用户认证系统 Django认证系统位置 Django认证系统同时处理认证和授权 Django认证系统包含的内 ...

  6. android 身份认证技术,Android平台上基于人脸识别的身份认证系统的设计与实现

    摘要: 随着移动互联网与人工智能技术的发展,基于个人特征的生物识别技术代替传统的身份验证方式已经是大势所趋.而人脸识别是生物识别技术的一个重要组成部分,拥有其他生物识别技术没有的独特优势.本文主要针对 ...

  7. Python+OpenCv实现AI人脸识别身份认证系统(2)——人脸数据采集、存储

    原 Python+OpenCv实现AI人脸识别身份认证系统(2)--人脸数据采集.存储 2019年07月02日 08:47:52 不脱发的程序猿 阅读数 602更多 所属专栏: 人脸识别身份认证系统设 ...

  8. 统一身份认证系统的简单看法

    [事件背景]洋葱服务为什么没被成功接盘?_搜狐科技_搜狐网 https://www.sohu.com/a/124452755_354899 今天无意中看到这则新闻,发现人家洋葱认证服务已经停运1年多啦 ...

  9. python初级编写:身份认证系统

    效果如下: ====================================== 欢迎进入身份认证系统v1.0 1.0登录 2.0退出 3.0认证 4.0修改密码 ============== ...

最新文章

  1. Platform Builder和Embedded visual C++简介
  2. FireFox与IE兼容性汇编
  3. cuda9.1 tensorflow1.6
  4. java short字段_Java Field setShort()用法及代码示例
  5. Java Socket
  6. python前段管理3
  7. 「mysql优化专题」这大概是一篇最好的mysql优化入门文章(1)
  8. ttf_openfont可以多次调用吗_西门子OB块、FC块、FB块、DB块之间有什么关系?如何调用?...
  9. @hdu - 3746@ Cyclic Nacklace
  10. 用canvas整个打飞机游戏
  11. C# v7.0版本中的local function
  12. 中山大学附属第一医院精准医学研究院 消化系统肿瘤研究于君课题组招聘启事...
  13. linux mysql jdk路径配置,Linux下的jdk1.5+eclipse+mysql开发环境配置的经验总结
  14. 一般柱子与柱子的距离_建筑中柱子之间的距离多少为好?
  15. shell中的getopt与getopts
  16. 【Java】IntelliJ IDEA 14.x 与 Tomcat 集成,创建并运行Java Web
  17. python中33个保留字的含义_Python的保留字。这是什么意思?
  18. Android 数独游戏开发,强逻辑的梳理
  19. 【C语言】实现简易扫雷(仿windows下扫雷)
  20. java语言实现视频音频采集_详解js的视频和音频采集

热门文章

  1. 【机房收费系统】——傻瓜式报表设计器制作报表模板
  2. 量子计算机相同数字相加怎么算,量子计算机如何分解两个质数乘积
  3. android开发工具箱专业版,安卓工具箱专业版下载-安卓工具箱专业版(Android Toolbox Pro) 安卓版v1.2.1-pc6手机下载...
  4. 微信报错:“code“:“40001“
  5. EPA消毒柜,空气净化器等等注册认证
  6. 人工智能项目取得成功,主要有哪几种方法?
  7. 用SOLIDWORKS雕刻万圣节南瓜
  8. python的dataframe的mul_熊猫-子集Python DataFrame
  9. 使用three.js搭建室内场景
  10. AutoCAD 2012开发环境配置