Django 自带密码加密,自定密码加密方式 及自定义验证方式

<div id="article_content" class="article_content csdn-tracking-statistics" style="overflow: hidden;" data-mod="popu_519" data-dsm="post">

在django1.6中,默认的加密方式是pbkdf_sha256,具体算法不表,一直以来用django的自带用户验证都十分顺手,今天有需求,需要修改默认加密方式为md5,具体方法为:

在settings.py中加入

[python]
    PASSWORD_HASHERS=(
  1. ,
  2. ,
  3. ,
  4. ,
  5. ,
  6. ,
  7. ,
  8. ,
  9. )
 'myproject.hashers.MyMD5PasswordHasher','django.contrib.auth.hashers.MD5PasswordHasher','django.contrib.auth.hashers.PBKDF2PasswordHasher','django.contrib.auth.hashers.PBKDF2SHA1PasswordHasher','django.contrib.auth.hashers.BCryptSHA256PasswordHasher','django.contrib.auth.hashers.BCryptPasswordHasher','django.contrib.auth.hashers.SHA1PasswordHasher','django.contrib.auth.hashers.CryptPasswordHasher',)</pre>





django会默认使用第一条加密方式。

这个是我自定义的加密方式,就是基本的md5,而django的MD5PasswordHasher是加盐的。

以下是我的自定义hashers.py:

<div class="dp-highlighter bg_python">
<div class="bar">
<div class="tools">[python] <a class="ViewSource" title="view plain" onclick="dp.sh.Toolbar.Command('ViewSource',this);return false;" href="#">copy

<div style="position: absolute; left: 277px; top: 713px; width: 16px; height: 16px; z-index: 99;"><object id="ZeroClipboardMovie_2" width="16" height="16" align="middle" bgcolor="#ffffff" data="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" type="application/x-shockwave-flash">

<span class="tracking-ad" data-mod="popu_169"> <a class="PrintSource" title="print" onclick="dp.sh.Toolbar.Command('PrintSource',this);return false;" href="#">?

    django.contrib.auth.hashersBasePasswordHasher,MD5PasswordHasher
  1. django.contrib.auth.hashersmask_hash
  2. hashlib
  3. MyMD5PasswordHasher(MD5PasswordHasher):
  4. algorithm=
  5. encode(,password,salt):
  6. password
  7. hash=hashlib.md5(password).hexdigest().upper()
  8. hash
  9. verify(,encoded):
  10. encoded_2=.encode(password,)
  11. encoded.upper()==encoded_2.upper()
  12. safe_summary(,encoded):
  13. OrderedDict([
  14. (_(),algorithm),
  15. (_(),),
  16. (_(),mask_hash(hash)),
  17. ])
class MyMD5PasswordHasher(MD5PasswordHasher):
algorithm = "mymd5"

  def encode(self,salt):
      assert password is not None
      hash = hashlib.md5(password).hexdigest().upper()
      return hash

  def verify(self,encoded):
      encoded_2 = self.encode(password,'')
      return encoded.upper() == encoded_2.upper()

  def safe_summary(self,encoded):
      return OrderedDict([
              (_('algorithm'),(_('salt'),''),(_('hash'),])
之后可以在数据库中看到,密码确实使用了自定义的加密方式。


然而仅仅修改这些,在配合django的authenticate验证时无法进行。

经过一些查找,发现需要在自定义authenticate。以下为方法:

在settings.py中加入以下:

<div class="dp-highlighter bg_python">
<div class="bar">
<div class="tools">[python] <a class="ViewSource" title="view plain" onclick="dp.sh.Toolbar.Command('ViewSource',this);return false;" href="#">copy
<div style="position: absolute; left: 277px; top: 1296px; width: 16px; height: 16px; z-index: 99;"><object id="ZeroClipboardMovie_3" width="16" height="16" align="middle" bgcolor="#ffffff" data="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" type="application/x-shockwave-flash">

<span class="tracking-ad" data-mod="popu_169"> <a class="PrintSource" title="print" onclick="dp.sh.Toolbar.Command('PrintSource',this);return false;" href="#">?

    AUTHENTICATION_BACKENDS=(
  1. ,
  2. )
以下代码为自定义的mybackend.py

<div class="dp-highlighter bg_python">
<div class="bar">
<div class="tools">[python] <a class="ViewSource" title="view plain" onclick="dp.sh.Toolbar.Command('ViewSource',this);return false;" href="#">copy
<div style="position: absolute; left: 277px; top: 1441px; width: 16px; height: 16px; z-index: 99;"><object id="ZeroClipboardMovie_4" width="16" height="16" align="middle" bgcolor="#ffffff" data="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" type="application/x-shockwave-flash">
<span class="tracking-ad" data-mod="popu_169"> <a class="PrintSource" title="print" onclick="dp.sh.Toolbar.Command('PrintSource',this);return false;" href="#">?

    hashlib
  1. promodels
  2. MyBackend(object):
  3. authenticate(,username=,password=):
  4. :
  5. user=models.M_User.objects.get(username=username)
  6. user
  7. Exception:
  8. hashlib.md5(password).hexdigest().upper()==user.password:
  9. user
  10. get_user(,user_id):
  11. :
  12. models.M_User.objects.get(id=user_id)
  13. Exception:
class MyBackend(object):
def authenticate(self,username=None,password=None):
try:
user = models.M_User.objects.get(username=username)
print user
except Exception:
print 'no user'
return None
if hashlib.md5(password).hexdigest().upper() == user.password:
return user
return None

  def get_user(self,user_id):
      try:
          return models.M_User.objects.get(id=user_id)
      except Exception:
          return None

之后验证成功。

当然经过这些修改后最终的安全性比起django自带的降低很多,但是需求就是这样的,必须满足。

完成需求的过程中查找了不少资料,最后还是在django文档中找到的答案,文档还是很全全面的,以后通读还是感觉有必要的。

                </div>

<p style="list-style: none; margin-top: 0px; margin-bottom: 0px; padding-top: 8px; padding-bottom: 8px; font-size: 14px; line-height: 26px; word-wrap: break-word; color: #444444; font-family: Simsun;"> 首先,引入模块:

</tr>
<tr>
<td id="copy3502" class="copyclass" style="color: #000000; list-style: none; margin: 0px; padding: 10px;" colspan="2" valign="top" bgcolor="#FFFFFF" height="auto">
<p style="list-style: none; margin-top: 0px; margin-bottom: 0px; padding-top: 8px; padding-bottom: 8px; font-size: 14px; word-wrap: break-word;">

from django.contrib.auth.hashers import make_password,check_password


<p style="list-style: none; margin-top: 0px; margin-bottom: 0px; padding-top: 8px; padding-bottom: 8px; font-size: 14px; word-wrap: break-word;">
生成密码:



make_password("www.111cn.net",None,'pbkdf2_sha256')

u'pbkdf2_sha256$12000$H6HRZD4DDiKg$RXBGBTiFWADyw+J9O7114vxKvysBVP+lz7oSYxkoic0='

</td>

</tr>

</table>
<p style="list-style: none; margin-top: 0px; margin-bottom: 0px; padding-top: 8px; padding-bottom: 8px; font-size: 14px; line-height: 26px; word-wrap: break-word; color: #444444; font-family: Simsun;">
这样就可以利用django自带的模块生成一组密码了,这个函数还有一个特点在于每次生成的密码还不一样:


<table style="color: #444444; font-family: Simsun; font-size: 15px; line-height: 26px; background: #ffbb77; width: 620px;" border="0" cellspacing="1" cellpadding="1" align="center">

</tr>
<tr>
<td id="copy3089" class="copyclass" style="color: #000000; list-style: none; margin: 0px; padding: 10px;" colspan="2" valign="top" bgcolor="#FFFFFF" height="auto">
<p style="list-style: none; margin-top: 0px; margin-bottom: 0px; padding-top: 8px; padding-bottom: 8px; font-size: 14px; word-wrap: break-word;">

make_password("www.111cn.net",'pbkdf2_sha256')

u'pbkdf2_sha256$12000$H6HRZD4DDiKg$RXBGBTiFWADyw+J9O7114vxKvysBVP+lz7oSYxkoic0='



make_password("www.111cn.net",'pbkdf2_sha256')

u'pbkdf2_sha256$12000$9l09rJd9MbQj$0tJVXBZFN6WwD/qI3WELdrRWOU7Inb7im3uB/np2PPg='



make_password("www.111cn.net",'pbkdf2_sha256') == make_password("www.111cn.net",

'pbkdf2_sha256')

False

</td>

</tr>

</table>
<p style="list-style: none; margin-top: 0px; margin-bottom: 0px; padding-top: 8px; padding-bottom: 8px; font-size: 14px; line-height: 26px; word-wrap: break-word; color: #444444; font-family: Simsun;">
既然每次生成的密文都不一样,如何验证用户提交过来的明文与密文匹配呢?这就靠check_password去做了,check_password使用非常简单,只需要告诉它明文和密文它就会返回False or True验证结果


<table style="color: #444444; font-family: Simsun; font-size: 15px; line-height: 26px; background: #ffbb77; width: 620px;" border="0" cellspacing="1" cellpadding="1" align="center">

</tr>
<tr>
<td id="copy9726" class="copyclass" style="color: #000000; list-style: none; margin: 0px; padding: 10px;" colspan="2" valign="top" bgcolor="#FFFFFF" height="auto">
<p style="list-style: none; margin-top: 0px; margin-bottom: 0px; padding-top: 8px; padding-bottom: 8px; font-size: 14px; word-wrap: break-word;">

text = "www.111cn.net"

passwd = make_password(text,'pbkdf2_sha256')

print passwd

pbkdf2_sha256$12000$xzMLhCNvQbb8$i1XDnJIpb/cRRGRX2x7Ym74RNfPRCUp5pbU6Sn+V3J0=

print check_password(text,passwd)

True

</td>

</tr>

</table>
<p style="list-style: none; margin-top: 0px; margin-bottom: 0px; padding-top: 8px; padding-bottom: 8px; font-size: 14px; line-height: 26px; word-wrap: break-word; color: #444444; font-family: Simsun;">
如果你不想每次都生成不同的密文,可以把make_password的第二个函数给一个固定的字符串,比如:


<table style="color: #444444; font-family: Simsun; font-size: 15px; line-height: 26px; background: #ffbb77; width: 620px;" border="0" cellspacing="1" cellpadding="1" align="center">

</tr>
<tr>
<td id="copy2782" class="copyclass" style="color: #000000; list-style: none; margin: 0px; padding: 10px;" colspan="2" valign="top" bgcolor="#FFFFFF" height="auto">

make_password(text,"a",'pbkdf2_sha256')

u'pbkdf2_sha256$12000$a$5HkIPczRZGSTKUBa5uzZmRuAWdp2Qe6Oemhdasvzv4Q='

make_password(text,'pbkdf2_sha256')

u'pbkdf2_sha256$12000$a$5HkIPczRZGSTKUBa5uzZmRuAWdp2Qe6Oemhdasvzv4Q='</td>

</tr>

</table>
<p style="list-style: none; margin-top: 0px; margin-bottom: 0px; padding-top: 8px; padding-bottom: 8px; font-size: 14px; line-height: 26px; word-wrap: break-word; color: #444444; font-family: Simsun;">
只要是任意字符串就可以,并且可以多个。但不能为空,如:


<table style="color: #444444; font-family: Simsun; font-size: 15px; line-height: 26px; background: #ffbb77; width: 620px;" border="0" cellspacing="1" cellpadding="1" align="center">

</tr>
<tr>
<td id="copy3223" class="copyclass" style="color: #000000; list-style: none; margin: 0px; padding: 10px;" colspan="2" valign="top" bgcolor="#FFFFFF" height="auto">
<p style="list-style: none; margin-top: 0px; margin-bottom: 0px; padding-top: 8px; padding-bottom: 8px; font-size: 14px; word-wrap: break-word;">

make_password(text,"",'pbkdf2_sha256')

u'pbkdf2_sha256$12000$KBcG81bWMAvd$aJNgfTOGFhOGogLSTE2goEM3ifKZZ1hydsuFEqnzHXU='



make_password(text,'pbkdf2_sha256')

u'pbkdf2_sha256$12000$fNv3YU4kgyLR$1FI8mxArDHt6Hj/eR72YCylGTAkW7YMWTj+wV4VHygY='

</td>

</tr>

</table>
<p style="list-style: none; margin-top: 0px; margin-bottom: 0px; padding-top: 8px; padding-bottom: 8px; font-size: 14px; line-height: 26px; word-wrap: break-word; color: #444444; font-family: Simsun;">
为空的字符串就相当于:

1


<table style="color: #444444; font-family: Simsun; font-size: 15px; line-height: 26px; background: #ffbb77; width: 620px;" border="0" cellspacing="1" cellpadding="1" align="center">

</tr>
<tr>
<td id="copy1264" class="copyclass" style="color: #000000; list-style: none; margin: 0px; padding: 10px;" colspan="2" valign="top" bgcolor="#FFFFFF" height="auto">


make_password(text,'pbkdf2_sha256')</td>

</tr>

</table>
<p style="list-style: none; margin-top: 0px; margin-bottom: 0px; padding-top: 8px; padding-bottom: 8px; font-size: 14px; line-height: 26px; word-wrap: break-word; color: #444444; font-family: Simsun;">
至于make_password第三个参数是表示生成密文的一种方式,根据文档给出的大概有这几种:


<table style="color: #444444; font-family: Simsun; font-size: 15px; line-height: 26px; background: #ffbb77; width: 620px;" border="0" cellspacing="1" cellpadding="1" align="center">

</tr>
<tr>
<td id="copy6708" class="copyclass" style="color: #000000; list-style: none; margin: 0px; padding: 10px;" colspan="2" valign="top" bgcolor="#FFFFFF" height="auto">
<p style="list-style: none; margin-top: 0px; margin-bottom: 0px; padding-top: 8px; padding-bottom: 8px; font-size: 14px; word-wrap: break-word;">
pbkdf2_sha256

pbkdf2_sha1

bcrypt_sha256

bcrypt

sha1

unsalted_md5

crypt

</td>

</tr>

</table>
<p style="list-style: none; margin-top: 0px; margin-bottom: 0px; padding-top: 8px; padding-bottom: 8px; font-size: 14px; line-height: 26px; word-wrap: break-word; color: #444444; font-family: Simsun;">
以上例子我使用了第一种加密方式pbkdf2_sha256,crypt和bcrypt都需要另外单独安装模块,unsalted_md5就是常见的md5加密,如果对加密哈希算法不是很了解,那么就使用django最新的哈希算法pbkdf2_sha256就好


版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


注:所有源代码均实测运行过。所有源代码均已上传CSDN,请有需要的朋友自行下载。
继承APIView和ViewSetMixin;作用也与APIView基本类似,提供了身份认证、权限校验、流量管理等。ViewSet在开发接口中不经常用。
一、Django介绍Python下有许多款不同的 Web 框架。Django是重量级选手中最有代表性的一位。许多成功的网站和APP都基于Django。Django 是一个开放源代码的 Web 应用框架,由 Python 写成。Django 遵守 BSD 版权,初次发布于 2005 年 7 月, 并于 2008 年 9 月发布了第一个正式版本 1.0 。Django学习线路Django 采用了 MVT 的软件设计模式,即模型(Model),视图(View)和模板(Template)。这个MVT模式并
本文从nginx快速掌握到使用,gunicorn快速掌握到使用,实现小白快速搭建django项目,并对可能出现的报错进行了分析
uniapp微信小程序订阅消息发送服务通知
Django终端打印SQL语句 1 Setting配置: 2 默认python 使用的MysqlDB连接,Python3 支持支持pymysql 所有需要在app里面的__init__加上下面配置:
url: re_path(&#39;authors/$&#39;, views.AuthorView.as_view()), re_path(&#39;book/(?P\d+)/$&#39;, vie
前提 关于html寻找路线: template 如果在各个APP中存在, Django 会优先找全局template 文件下的html文件,如果全局下的template文件没有相关的html Djan
// GET请求request.GET // POST请求request.POST // 处理文件上传请求request.FILES // 处理如checkbox等多选 接受列表request.get
from bs4 import BeautifulSoup#kindeditordef kindeditor(request): s = &#39;&#39;&#39; &lt;li&gt;&lt;s
view.py 配置 html 配置
from django.http import JsonResponse JsonResponse 里面代码会加这一个响应头 kwargs.setdefault(&#39;content_type&#
#下面两种是基于QuerySet查询 也就是说SQL中用的jion连表的方式查询books = models.UserInfo.objects.all() print(type(books)) &gt
return HttpResponse(&quot;OK&quot;) 返回一个字符串 return redirect(&quot;/index/&quot;) 返回URL return render
from django.http import JsonResponse JsonResponse 里面代码会加这一个响应头 kwargs.setdefault(&#39;content_type&#
浏览器有一个很重要的概念——同源策略(Same-Origin Policy)。所谓同源是指,域名,协议,端口相同。不同源的客户端脚本(javascript、ActionScript)在没明确授权的情况
自动发送 &gt; 依赖jQuery文件 实例--&gt;GET请求: 手动发送 &gt; 依赖浏览器XML对象(也叫原生ajax) Ajax主要就是使用 【XmlHttpRequest】对象来完成请
#下面两种是基于QuerySet查询 也就是说SQL中用的jion连表的方式查询books = models.UserInfo.objects.all() print(type(books)) &gt
// GET请求request.GET // POST请求request.POST // 处理文件上传请求request.FILES // 处理如checkbox等多选 接受列表request.get
return HttpResponse(&quot;OK&quot;) 返回一个字符串 return redirect(&quot;/index/&quot;) 返回URL return render