登录功能

上一篇文章,我们完善了注册的功能。这一次完善登录功能。E:\djstudy\PeiQi1\static\peiqi1\main\js\mine.js
登录功能验证的views:

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

def login(request):
    if request.method == 'GET':
        data = {
            'title': '登录',
        }

        return render(request, 'user/login.html', context=data)

    elif request.method == 'POST':
        username = request.POST.get('username')
        password = request.POST.get('password')
        print(password)
        users = peiqi1user.objects.filter(u_usename=username)
        if users.exists():   # 如果用户名存在
            user = users.first()

            if check_password(password, user.u_password):  # 哈希验证密码
                # 使用cookie或者session将用户登录状态存下
                request.session['user_id'] = user.id
                return redirect(reverse('peiqi1:mine'))  #
            else:
                print('密码错误')
                return redirect(reverse('peiqi1:login'))

        print('用户不存在')
        return redirect(reverse('peiqi1:login'))

但是我们经过版本升级之后,密码验证策略不兼容:

  • 第一版本,注册之手,密码是明文
  • 第二版本,注册之后,密码时hash值
  • 第三版本,注册之后,密码是hash+时间数列

假定第三版本,让你同时兼容第一二版本,如何实现?
对请求的参数添加版本号,没添加的就是旧版本
对于低版本使用特定认证(密码+短信验证),认证完,在会话中将低版本的版本号存储下来。

测试:
我们在输入了正确的用户名密码之后,可以成功跳转到个人中心的界面

个人中心搭建

头部外观

在mine.css中添加:

/*
底部图标和文字
*/

footer .mine_icon span {
    background: url(/static/img/mine_selected.png) no-repeat;
    background-size: 0.513889rem;
}

footer .mine_icom dd {
    color: orange;

}

#mine {
    width: 100%;
    height: 100%;
    position: absolute;
    z-index: +10;
    background: whitesmoke;
    overflow: hidden;
    padding-top: 4rem;
    padding-bottom: 1.5rem;
}

/*
内容容器
*/

.fixed {
    position: fixed;
    top: 0;
    width: 100%;
    height: 4rem;
    background: pink;
    padding-top: 0.5rem;
}

.fixed > span {
    display: block;
    width: 2rem;
    height: 2rem;
    float: left;
    margin: 0 0.3rem 0;
    font-size: 1.5rem;
    color: black;
    background: white;
    text-align: center;
    border-radius: 50%;
    line-height: 1.8rem;
}

.fixed p {
    margin-bottom: 0.5rem;
    font-size: 0.5rem;
    color: white;
}

.fixed p span:first-child {
    color: black;
}

.fixed p span:last-child {
    color: red;
    display: inline-block;
    text-indent: 0.3rem;
}

#regis {
    position: absolute;
    right: 0.3rem;
    top: 1.3rem;
    color: white;
    font-size: 1rem;
}

.fixed p:last-child {
    background: #f0e000;
    width: 100%;
    position: absolute;
    text-align: center;
    bottom: 0;
    margin-bottom: 0;
    font-size: 0.4rem;
    line-height: 0.5rem;
    height: 1rem;
}

.fixed p:last-child span {
    margin: 0.2rem 0;
}

.fixed p:last-child span:first-child {
    color: red;
}

.fixed p:last-child span:last-child {
    color: white;
}

因为css重名,将base_main.html还有base.css中修改。

base_main.htm:

<a href="{% url 'peiqi1:mine' %}" class="mine_icon">    /* mine改为 mine_icon */

base.css:

footer .mine_icon span {
    background: url(/static/img/mine.png) no-repeat;
    background-size: 0.513889rem;
}                /* mine改为 mine_icon */

mine.html:

{% extends 'base_main.html' %}
{% load static %}

{% block ext_css %}
    {{ block.super }}
    <link rel="stylesheet" href="{% static 'peiqi1/main/css/mine.css' %}">
{% endblock %}


{% block content %}
<div id="mine">
<div class="fixed">
    <span class="glyphicon glyphicon-user"> {# 黑色人物头像,引用的bootstrap上 #}
    </span>
    <p>未登录</p>
    <p>
        <span class="glyphicon glyphicon-fire"></span>
        <span>等级</span>
    </p>
    <div id="regis">注册</div>
    <p>
        <span class="glyphicon glyphicon-heart"></span>
        <span>商品收藏</span>
    </p>
</div>
</div>
{% endblock %}

views:

测试:


功能菜单外观

mine.css:

/*
个人中心中的各种入口
*/

.mine {
    width: 100%;
    height: 100%;
    overflow: auto;
    padding-bottom: 1.5rem;
    font-size: 0.4rem;
}

.mine p {
    line-height: 1.5rem;
    padding: 0 0.3rem;
    background: white;
    border-bottom: 0.04rem solid lightyellow;
}

.mine p a {
    color: grey;
    float: right;
}


.mine #nav, .mine menu {
    padding: 0.5rem 0 0.3rem;
    margin-bottom: 0.4rem;
    background: white;
}

.mine #nav ul, .mine menu ul {
    display: flex;
    justify-content: space-around;
}

.mine #nav ul li dl, .mine menu ul li dl {
    text-align: center;
}

.mine #nav ul li dl dt, .mine menu ul li dl dt {
    width: 100%;
    line-height: 1rem;
}

.mine #nav ul li dl dt span, .mine menu ul li dl dt span {
    font-size: 0.5rem;
}

.mine menu ul {
    flex-wrap: wrap;
}

.mine menu ul li {
    width: 25%;
}

.mine menu ul li:last-child {
    width: 100%;
}

.mine menu ul li:last-child dl {
    width: 25%;
}

.mine p:last-child > a {
    line-height: 1.5rem;
    text-align: center;
    width: 100%;
    display: block;
    float: none;
}

mine.html

{% extends 'base_main.html' %}
{% load static %}

{% block ext_css %}
    {{ block.super }}
    <link rel="stylesheet" href="{% static 'peiqi1/main/css/mine.css' %}">
{% endblock %}


{% block content %}
<div id="mine">
<div class="fixed">
    <span class="glyphicon glyphicon-user"> {# 黑色人物头像,引用的bootstrap上 #}
    </span>
    <p>未登录</p>
    <p>
        <span class="glyphicon glyphicon-fire"></span>
        <span>等级</span>
    </p>
    <div id="regis">注册</div>
    <p>
        <span class="glyphicon glyphicon-heart"></span>
        <span>商品收藏</span>
    </p>
</div>

<div class="mine">
    <p>
        <span>全部订单</span>
        <a href="#">全部订单></a>
    </p>
    <nav id="nav">
        <ul>
            <li>
                <dl>
                    <dt>
                        <span class="glyphicon glyphicon-usd"></span>
                    </dt>
                    <dd>待付款</dd>
                </dl>
            </li>
            <li>
                <dl>
                    <dt>
                        <span class="glyphicon glyphicon-envelope"></span>
                    </dt>
                    <dd>待收货</dd>
                </dl>
            </li>
            <li>
                <dl>
                    <dt>
                        <span class="glyphicon glyphicon-pencil"></span>
                    </dt>
                    <dd>待评价</dd>
                </dl>
            </li>
            <li>
                <dl>
                    <dt>
                        <span class="glyphicon glyphicon-retweet"></span>
                    </dt>
                    <dd>退款/售后</dd>
                </dl>
            </li>
        </ul>
    </nav>  {# <nav> 标签定义导航链接的部分。 #}

</div>
</div>
{% endblock %}

测试:

接着使用不同的选择器来添加更多的功能按钮:
mine.html:

<div class="mine">
    <p>
        <span>全部订单</span>
        <a href="#">全部订单></a>
    </p>
    <nav id="nav">
        <ul>
            <li>
                <dl>
                    <dt>
                        <span class="glyphicon glyphicon-usd"></span>
                    </dt>
                    <dd>待付款</dd>
                </dl>
            </li>
            <li>
                <dl>
                    <dt>
                        <span class="glyphicon glyphicon-envelope"></span>
                    </dt>
                    <dd>待收货</dd>
                </dl>
            </li>
            <li>
                <dl>
                    <dt>
                        <span class="glyphicon glyphicon-pencil"></span>
                    </dt>
                    <dd>待评价</dd>
                </dl>
            </li>
            <li>
                <dl>
                    <dt>
                        <span class="glyphicon glyphicon-retweet"></span>
                    </dt>
                    <dd>退款/售后</dd>
                </dl>
            </li>
        </ul>
    </nav>  {# <nav> 标签定义导航链接的部分。 #}
    <menu>
        <ul>
            <li>
                <dl>
                    <dt>
                        <span class="glyphicon glyphicon-bullhorn"></span>
                    </dt>
                    <dd>积分商城</dd>
                </dl>
            </li>
            <li>
                <dl>
                    <dt>
                        <span class="glyphicon glyphicon-credit-card"></span>
                    </dt>
                    <dd>优惠券</dd>
                </dl>
            </li>
            <li>
                <dl>
                    <dt>
                        <span class="glyphicon glyphicon-import"></span>
                    </dt>
                    <dd>收货地址</dd>
                </dl>
            </li>
            <li>
                <dl>
                    <dt>
                        <span class="glyphicon glyphicon-phone-alt"></span>
                    </dt>
                    <dd>客服/反馈</dd>
                </dl>
            </li>
            <li>
                <dl>
                    <dt>
                        <span class="glyphicon glyphicon-asterisk"></span>
                    </dt>
                    <dd>关于我们</dd>
                </dl>
            </li>
        </ul>
    </menu>
</div>
</div>
{% endblock %}

测试:

退出登录按钮外观

我们要添加一个退出登录按钮,并且只有在登录状态下才能看到此按钮。
引入一个参数来判断是否登录
views:

def mine(request):

    user_id = request.session.get('user_id')

    data = {
        'title': '我的',
        'is_login': False  # 判断是否登录,默认为未登录
    }

    if user_id:     # 如果登录,有user_id
        data['is_login'] = True

html:

    {% if is_login %}  {# 如果登录了,就显示退出登录按钮 #}
        <p>
            <a href="#">退出登录</a>
        </p>
    {% endif %}


头部逻辑

未登录按钮的点击事件



在头部外观中,对于未登录的用户来说,应该显示黑色头像,并且未登录可以点击跳转至登录界面,登录完成之后,头像框应该显用户头像,未登录更改成对应的用户名。
settings:

# 用于服务器响应给客户端的头像地址
MEDIA_KEY_PREFIX = '/static/uploads/'

views:

def mine(request):

    user_id = request.session.get('user_id')

    data = {
        'title': '我的',
        'is_login': False  # 判断是否登录,默认为未登录
    }

    if user_id:     # 如果登录,有user_id
        user = peiqi1user.objects.get(pk=user_id)
        data['is_login'] = True
        data['username'] = user.u_usename  # 用户名
        data['icon'] = MEDIA_KEY_PREFIX+user.u_icon.url

    return render(request, 'main/mine.html',context=data)

mine.html:

    <div id="mine">
        <div class="fixed">
        <span>
            {% if is_login %}
<img class="u_icon" src="{{ icon }}" alt="{{ username }}">  {# 添加头像样式u_icon #}
                {% else %}
                <span class="glyphicon glyphicon-user"></span>{# 黑色人物头像,引用的bootstrap上 #}
            {% endif %}
        </span>



            {% if is_login %}  {# 如果登录就显示用户名 #}
                <p>{{ username }}</p>
            {% else %}
                <p>未登录</p>
            {% endif %}

            <p>
                <span class="glyphicon glyphicon-fire"></span>
                <span>等级</span>
            </p>

            {% if not is_login %}  {# 如果没有登录就显示注册 #}
                <div id="regis">注册</div>
            {% endif %}
            <p>
                <span class="glyphicon glyphicon-heart"></span>
                <span>商品收藏</span>
            </p>
        </div>

mine.css中添加头像的样式:

.fixed > span> .u_icon {
    width: 2rem;
    height: 2rem;
    border-radius: 50%;
}

注册按钮的点击事件

退出逻辑

点击退出登录按钮就可以退出

添加url:

url(r'^logout/', views.logout, name='logout'),

新建mine.js:
PeiQi1\static\peiqi1\main\js\mine.js

$(function () {

    $('#not_login').click(function(){

        window.open('/peiqi1/login',target='_self');   /* 利用js在当前窗口打开页面*/

    })

})

views:

def logout(request):
    request.session.flush()  # 清除session
    return redirect(reverse('peiqi1:mine'))

mine.html:

{% extends 'base_main.html' %}
{% load static %}

{% block ext_css %}
    {{ block.super }}
    <link rel="stylesheet" href="{% static 'peiqi1/main/css/mine.css' %}">
{% endblock %}

{% block ext_js %}
    {{ block.super }}
    <script type="text/javascript" src="{% static 'peiqi1/main/js/mine.js' %}"></script>  {# 添加mine.js到前端中 #}
{% endblock %}

{% block content %}
    <div id="mine">
        <div class="fixed">
        <span>
            {% if is_login %}
                <img class="u_icon" src="{{ icon }}" alt="{{ username }}">  {# 添加头像样式u_icon #}
            {% else %}
                <span class="glyphicon glyphicon-user"></span>{# 黑色人物头像,引用的bootstrap上 #}
            {% endif %}
        </span>



            {% if is_login %}  {# 如果登录就显示用户名 #}
                <p>{{ username }}</p>
            {% else %}
                <p id="not_login">未登录</p>   {# 添加点击事件 #}
            {% endif %}

            <p>
                <span class="glyphicon glyphicon-fire"></span>
                <span>等级</span>
            </p>

            {% if not is_login %}  {# 如果没有登录就显示注册 #}
                <div id="regis">注册</div>
            {% endif %}
            <p>
                <span class="glyphicon glyphicon-heart"></span>
                <span>商品收藏</span>
            </p>
        </div>

        <div class="mine">
            <p>
                <span>全部订单</span>
                <a href="#">全部订单></a>
            </p>
            <nav id="nav">
                <ul>
                    <li>
                        <dl>
                            <dt>
                                <span class="glyphicon glyphicon-usd"></span>
                            </dt>
                            <dd>待付款</dd>
                        </dl>
                    </li>
                    <li>
                        <dl>
                            <dt>
                                <span class="glyphicon glyphicon-envelope"></span>
                            </dt>
                            <dd>待收货</dd>
                        </dl>
                    </li>
                    <li>
                        <dl>
                            <dt>
                                <span class="glyphicon glyphicon-pencil"></span>
                            </dt>
                            <dd>待评价</dd>
                        </dl>
                    </li>
                    <li>
                        <dl>
                            <dt>
                                <span class="glyphicon glyphicon-retweet"></span>
                            </dt>
                            <dd>退款/售后</dd>
                        </dl>
                    </li>
                </ul>
            </nav>
            {# <nav> 标签定义导航链接的部分。 #}
            <menu>
                <ul>
                    <li>
                        <dl>
                            <dt>
                                <span class="glyphicon glyphicon-bullhorn"></span>
                            </dt>
                            <dd>积分商城</dd>
                        </dl>
                    </li>
                    <li>
                        <dl>
                            <dt>
                                <span class="glyphicon glyphicon-credit-card"></span>
                            </dt>
                            <dd>优惠券</dd>
                        </dl>
                    </li>
                    <li>
                        <dl>
                            <dt>
                                <span class="glyphicon glyphicon-import"></span>
                            </dt>
                            <dd>收货地址</dd>
                        </dl>
                    </li>
                    <li>
                        <dl>
                            <dt>
                                <span class="glyphicon glyphicon-phone-alt"></span>
                            </dt>
                            <dd>客服/反馈</dd>
                        </dl>
                    </li>
                    <li>
                        <dl>
                            <dt>
                                <span class="glyphicon glyphicon-asterisk"></span>
                            </dt>
                            <dd>关于我们</dd>
                        </dl>
                    </li>
                </ul>
            </menu>
            {% if is_login %}  {# 如果登录了,就显示退出登录按钮 #}
                <p>
                    <a href="{% url 'peiqi1:logout' %}">退出登录</a>
                </p>
            {% endif %}
        </div>
    </div>
{% endblock %}

9-12行引入mine.js
133-137行给“退出登录”按钮添加退出登录的url。

这样我们就实现了点击退出登录按钮,头部就会显示未登录状态,点击“未登录”,就可以跳转到登录界面。

外部密码安全策略

我们先前的安全策略加密了数据库密码,只是防了内鬼(管理服务器的人),
但是没有防住外部进行抓包,网络监控的人,他们可以将,16年315晚会,连接一个提前配置好的路由器,然后随便打开几个app,之后就可以从路由器后台获取到各种个人信息,比如外卖地址,订单内容,家庭地址,等等。
提醒我们:

  • 免费的wifi不要随便白嫖,有时候被骗是因为知道你的个人信息太多,感觉真的就特别熟悉你。
  • 目前由于中国的互联网成长过快,就会造成网络不够安全的缺陷,一些app在传输数据的时候没有按照规范去加密数据,或者是加密等级低,数据很容易被抓包破解。

当你登录时,提交的密码需要进行不可逆加密,就是用哈希算法,这里使用js中的md5加密(编程语言基本上都有md5加密)。

找到实现md5算法的js文件:

/**
 * [js-md5]{@link https://github.com/emn178/js-md5}
 *
 * @namespace md5
 * @version 0.7.3
 * @author Chen, Yi-Cyuan [emn178@gmail.com]
 * @copyright Chen, Yi-Cyuan 2014-2017
 * @license MIT
 */
(function () {
  'use strict';

  var ERROR = 'input is invalid type';
  var WINDOW = typeof window === 'object';
  var root = WINDOW ? window : {};
  if (root.JS_MD5_NO_WINDOW) {
    WINDOW = false;
  }
  var WEB_WORKER = !WINDOW && typeof self === 'object';
  var NODE_JS = !root.JS_MD5_NO_NODE_JS && typeof process === 'object' && process.versions && process.versions.node;
  if (NODE_JS) {
    root = global;
  } else if (WEB_WORKER) {
    root = self;
  }
  var COMMON_JS = !root.JS_MD5_NO_COMMON_JS && typeof module === 'object' && module.exports;
  var AMD = typeof define === 'function' && define.amd;
  var ARRAY_BUFFER = !root.JS_MD5_NO_ARRAY_BUFFER && typeof ArrayBuffer !== 'undefined';
  var HEX_CHARS = '0123456789abcdef'.split('');
  var EXTRA = [128, 32768, 8388608, -2147483648];
  var SHIFT = [0, 8, 16, 24];
  var OUTPUT_TYPES = ['hex', 'array', 'digest', 'buffer', 'arrayBuffer', 'base64'];
  var BASE64_ENCODE_CHAR = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'.split('');

  var blocks = [], buffer8;
  if (ARRAY_BUFFER) {
    var buffer = new ArrayBuffer(68);
    buffer8 = new Uint8Array(buffer);
    blocks = new Uint32Array(buffer);
  }

  if (root.JS_MD5_NO_NODE_JS || !Array.isArray) {
    Array.isArray = function (obj) {
      return Object.prototype.toString.call(obj) === '[object Array]';
    };
  }

  if (ARRAY_BUFFER && (root.JS_MD5_NO_ARRAY_BUFFER_IS_VIEW || !ArrayBuffer.isView)) {
    ArrayBuffer.isView = function (obj) {
      return typeof obj === 'object' && obj.buffer && obj.buffer.constructor === ArrayBuffer;
    };
  }

  /**
   * @method hex
   * @memberof md5
   * @description Output hash as hex string
   * @param {String|Array|Uint8Array|ArrayBuffer} message message to hash
   * @returns {String} Hex string
   * @example
   * md5.hex('The quick brown fox jumps over the lazy dog');
   * // equal to
   * md5('The quick brown fox jumps over the lazy dog');
   */
  /**
   * @method digest
   * @memberof md5
   * @description Output hash as bytes array
   * @param {String|Array|Uint8Array|ArrayBuffer} message message to hash
   * @returns {Array} Bytes array
   * @example
   * md5.digest('The quick brown fox jumps over the lazy dog');
   */
  /**
   * @method array
   * @memberof md5
   * @description Output hash as bytes array
   * @param {String|Array|Uint8Array|ArrayBuffer} message message to hash
   * @returns {Array} Bytes array
   * @example
   * md5.array('The quick brown fox jumps over the lazy dog');
   */
  /**
   * @method arrayBuffer
   * @memberof md5
   * @description Output hash as ArrayBuffer
   * @param {String|Array|Uint8Array|ArrayBuffer} message message to hash
   * @returns {ArrayBuffer} ArrayBuffer
   * @example
   * md5.arrayBuffer('The quick brown fox jumps over the lazy dog');
   */
  /**
   * @method buffer
   * @deprecated This maybe confuse with Buffer in node.js. Please use arrayBuffer instead.
   * @memberof md5
   * @description Output hash as ArrayBuffer
   * @param {String|Array|Uint8Array|ArrayBuffer} message message to hash
   * @returns {ArrayBuffer} ArrayBuffer
   * @example
   * md5.buffer('The quick brown fox jumps over the lazy dog');
   */
  /**
   * @method base64
   * @memberof md5
   * @description Output hash as base64 string
   * @param {String|Array|Uint8Array|ArrayBuffer} message message to hash
   * @returns {String} base64 string
   * @example
   * md5.base64('The quick brown fox jumps over the lazy dog');
   */
  var createOutputMethod = function (outputType) {
    return function (message) {
      return new Md5(true).update(message)[outputType]();
    };
  };

  /**
   * @method create
   * @memberof md5
   * @description Create Md5 object
   * @returns {Md5} Md5 object.
   * @example
   * var hash = md5.create();
   */
  /**
   * @method update
   * @memberof md5
   * @description Create and update Md5 object
   * @param {String|Array|Uint8Array|ArrayBuffer} message message to hash
   * @returns {Md5} Md5 object.
   * @example
   * var hash = md5.update('The quick brown fox jumps over the lazy dog');
   * // equal to
   * var hash = md5.create();
   * hash.update('The quick brown fox jumps over the lazy dog');
   */
  var createMethod = function () {
    var method = createOutputMethod('hex');
    if (NODE_JS) {
      method = nodeWrap(method);
    }
    method.create = function () {
      return new Md5();
    };
    method.update = function (message) {
      return method.create().update(message);
    };
    for (var i = 0; i < OUTPUT_TYPES.length; ++i) {
      var type = OUTPUT_TYPES[i];
      method[type] = createOutputMethod(type);
    }
    return method;
  };

  var nodeWrap = function (method) {
    var crypto = eval("require('crypto')");
    var Buffer = eval("require('buffer').Buffer");
    var nodeMethod = function (message) {
      if (typeof message === 'string') {
        return crypto.createHash('md5').update(message, 'utf8').digest('hex');
      } else {
        if (message === null || message === undefined) {
          throw ERROR;
        } else if (message.constructor === ArrayBuffer) {
          message = new Uint8Array(message);
        }
      }
      if (Array.isArray(message) || ArrayBuffer.isView(message) ||
        message.constructor === Buffer) {
        return crypto.createHash('md5').update(new Buffer(message)).digest('hex');
      } else {
        return method(message);
      }
    };
    return nodeMethod;
  };

  /**
   * Md5 class
   * @class Md5
   * @description This is internal class.
   * @see {@link md5.create}
   */
  function Md5(sharedMemory) {
    if (sharedMemory) {
      blocks[0] = blocks[16] = blocks[1] = blocks[2] = blocks[3] =
      blocks[4] = blocks[5] = blocks[6] = blocks[7] =
      blocks[8] = blocks[9] = blocks[10] = blocks[11] =
      blocks[12] = blocks[13] = blocks[14] = blocks[15] = 0;
      this.blocks = blocks;
      this.buffer8 = buffer8;
    } else {
      if (ARRAY_BUFFER) {
        var buffer = new ArrayBuffer(68);
        this.buffer8 = new Uint8Array(buffer);
        this.blocks = new Uint32Array(buffer);
      } else {
        this.blocks = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
      }
    }
    this.h0 = this.h1 = this.h2 = this.h3 = this.start = this.bytes = this.hBytes = 0;
    this.finalized = this.hashed = false;
    this.first = true;
  }

  /**
   * @method update
   * @memberof Md5
   * @instance
   * @description Update hash
   * @param {String|Array|Uint8Array|ArrayBuffer} message message to hash
   * @returns {Md5} Md5 object.
   * @see {@link md5.update}
   */
  Md5.prototype.update = function (message) {
    if (this.finalized) {
      return;
    }

    var notString, type = typeof message;
    if (type !== 'string') {
      if (type === 'object') {
        if (message === null) {
          throw ERROR;
        } else if (ARRAY_BUFFER && message.constructor === ArrayBuffer) {
          message = new Uint8Array(message);
        } else if (!Array.isArray(message)) {
          if (!ARRAY_BUFFER || !ArrayBuffer.isView(message)) {
            throw ERROR;
          }
        }
      } else {
        throw ERROR;
      }
      notString = true;
    }
    var code, index = 0, i, length = message.length, blocks = this.blocks;
    var buffer8 = this.buffer8;

    while (index < length) {
      if (this.hashed) {
        this.hashed = false;
        blocks[0] = blocks[16];
        blocks[16] = blocks[1] = blocks[2] = blocks[3] =
        blocks[4] = blocks[5] = blocks[6] = blocks[7] =
        blocks[8] = blocks[9] = blocks[10] = blocks[11] =
        blocks[12] = blocks[13] = blocks[14] = blocks[15] = 0;
      }

      if (notString) {
        if (ARRAY_BUFFER) {
          for (i = this.start; index < length && i < 64; ++index) {
            buffer8[i++] = message[index];
          }
        } else {
          for (i = this.start; index < length && i < 64; ++index) {
            blocks[i >> 2] |= message[index] << SHIFT[i++ & 3];
          }
        }
      } else {
        if (ARRAY_BUFFER) {
          for (i = this.start; index < length && i < 64; ++index) {
            code = message.charCodeAt(index);
            if (code < 0x80) {
              buffer8[i++] = code;
            } else if (code < 0x800) {
              buffer8[i++] = 0xc0 | (code >> 6);
              buffer8[i++] = 0x80 | (code & 0x3f);
            } else if (code < 0xd800 || code >= 0xe000) {
              buffer8[i++] = 0xe0 | (code >> 12);
              buffer8[i++] = 0x80 | ((code >> 6) & 0x3f);
              buffer8[i++] = 0x80 | (code & 0x3f);
            } else {
              code = 0x10000 + (((code & 0x3ff) << 10) | (message.charCodeAt(++index) & 0x3ff));
              buffer8[i++] = 0xf0 | (code >> 18);
              buffer8[i++] = 0x80 | ((code >> 12) & 0x3f);
              buffer8[i++] = 0x80 | ((code >> 6) & 0x3f);
              buffer8[i++] = 0x80 | (code & 0x3f);
            }
          }
        } else {
          for (i = this.start; index < length && i < 64; ++index) {
            code = message.charCodeAt(index);
            if (code < 0x80) {
              blocks[i >> 2] |= code << SHIFT[i++ & 3];
            } else if (code < 0x800) {
              blocks[i >> 2] |= (0xc0 | (code >> 6)) << SHIFT[i++ & 3];
              blocks[i >> 2] |= (0x80 | (code & 0x3f)) << SHIFT[i++ & 3];
            } else if (code < 0xd800 || code >= 0xe000) {
              blocks[i >> 2] |= (0xe0 | (code >> 12)) << SHIFT[i++ & 3];
              blocks[i >> 2] |= (0x80 | ((code >> 6) & 0x3f)) << SHIFT[i++ & 3];
              blocks[i >> 2] |= (0x80 | (code & 0x3f)) << SHIFT[i++ & 3];
            } else {
              code = 0x10000 + (((code & 0x3ff) << 10) | (message.charCodeAt(++index) & 0x3ff));
              blocks[i >> 2] |= (0xf0 | (code >> 18)) << SHIFT[i++ & 3];
              blocks[i >> 2] |= (0x80 | ((code >> 12) & 0x3f)) << SHIFT[i++ & 3];
              blocks[i >> 2] |= (0x80 | ((code >> 6) & 0x3f)) << SHIFT[i++ & 3];
              blocks[i >> 2] |= (0x80 | (code & 0x3f)) << SHIFT[i++ & 3];
            }
          }
        }
      }
      this.lastByteIndex = i;
      this.bytes += i - this.start;
      if (i >= 64) {
        this.start = i - 64;
        this.hash();
        this.hashed = true;
      } else {
        this.start = i;
      }
    }
    if (this.bytes > 4294967295) {
      this.hBytes += this.bytes / 4294967296 << 0;
      this.bytes = this.bytes % 4294967296;
    }
    return this;
  };

  Md5.prototype.finalize = function () {
    if (this.finalized) {
      return;
    }
    this.finalized = true;
    var blocks = this.blocks, i = this.lastByteIndex;
    blocks[i >> 2] |= EXTRA[i & 3];
    if (i >= 56) {
      if (!this.hashed) {
        this.hash();
      }
      blocks[0] = blocks[16];
      blocks[16] = blocks[1] = blocks[2] = blocks[3] =
      blocks[4] = blocks[5] = blocks[6] = blocks[7] =
      blocks[8] = blocks[9] = blocks[10] = blocks[11] =
      blocks[12] = blocks[13] = blocks[14] = blocks[15] = 0;
    }
    blocks[14] = this.bytes << 3;
    blocks[15] = this.hBytes << 3 | this.bytes >>> 29;
    this.hash();
  };

  Md5.prototype.hash = function () {
    var a, b, c, d, bc, da, blocks = this.blocks;

    if (this.first) {
      a = blocks[0] - 680876937;
      a = (a << 7 | a >>> 25) - 271733879 << 0;
      d = (-1732584194 ^ a & 2004318071) + blocks[1] - 117830708;
      d = (d << 12 | d >>> 20) + a << 0;
      c = (-271733879 ^ (d & (a ^ -271733879))) + blocks[2] - 1126478375;
      c = (c << 17 | c >>> 15) + d << 0;
      b = (a ^ (c & (d ^ a))) + blocks[3] - 1316259209;
      b = (b << 22 | b >>> 10) + c << 0;
    } else {
      a = this.h0;
      b = this.h1;
      c = this.h2;
      d = this.h3;
      a += (d ^ (b & (c ^ d))) + blocks[0] - 680876936;
      a = (a << 7 | a >>> 25) + b << 0;
      d += (c ^ (a & (b ^ c))) + blocks[1] - 389564586;
      d = (d << 12 | d >>> 20) + a << 0;
      c += (b ^ (d & (a ^ b))) + blocks[2] + 606105819;
      c = (c << 17 | c >>> 15) + d << 0;
      b += (a ^ (c & (d ^ a))) + blocks[3] - 1044525330;
      b = (b << 22 | b >>> 10) + c << 0;
    }

    a += (d ^ (b & (c ^ d))) + blocks[4] - 176418897;
    a = (a << 7 | a >>> 25) + b << 0;
    d += (c ^ (a & (b ^ c))) + blocks[5] + 1200080426;
    d = (d << 12 | d >>> 20) + a << 0;
    c += (b ^ (d & (a ^ b))) + blocks[6] - 1473231341;
    c = (c << 17 | c >>> 15) + d << 0;
    b += (a ^ (c & (d ^ a))) + blocks[7] - 45705983;
    b = (b << 22 | b >>> 10) + c << 0;
    a += (d ^ (b & (c ^ d))) + blocks[8] + 1770035416;
    a = (a << 7 | a >>> 25) + b << 0;
    d += (c ^ (a & (b ^ c))) + blocks[9] - 1958414417;
    d = (d << 12 | d >>> 20) + a << 0;
    c += (b ^ (d & (a ^ b))) + blocks[10] - 42063;
    c = (c << 17 | c >>> 15) + d << 0;
    b += (a ^ (c & (d ^ a))) + blocks[11] - 1990404162;
    b = (b << 22 | b >>> 10) + c << 0;
    a += (d ^ (b & (c ^ d))) + blocks[12] + 1804603682;
    a = (a << 7 | a >>> 25) + b << 0;
    d += (c ^ (a & (b ^ c))) + blocks[13] - 40341101;
    d = (d << 12 | d >>> 20) + a << 0;
    c += (b ^ (d & (a ^ b))) + blocks[14] - 1502002290;
    c = (c << 17 | c >>> 15) + d << 0;
    b += (a ^ (c & (d ^ a))) + blocks[15] + 1236535329;
    b = (b << 22 | b >>> 10) + c << 0;
    a += (c ^ (d & (b ^ c))) + blocks[1] - 165796510;
    a = (a << 5 | a >>> 27) + b << 0;
    d += (b ^ (c & (a ^ b))) + blocks[6] - 1069501632;
    d = (d << 9 | d >>> 23) + a << 0;
    c += (a ^ (b & (d ^ a))) + blocks[11] + 643717713;
    c = (c << 14 | c >>> 18) + d << 0;
    b += (d ^ (a & (c ^ d))) + blocks[0] - 373897302;
    b = (b << 20 | b >>> 12) + c << 0;
    a += (c ^ (d & (b ^ c))) + blocks[5] - 701558691;
    a = (a << 5 | a >>> 27) + b << 0;
    d += (b ^ (c & (a ^ b))) + blocks[10] + 38016083;
    d = (d << 9 | d >>> 23) + a << 0;
    c += (a ^ (b & (d ^ a))) + blocks[15] - 660478335;
    c = (c << 14 | c >>> 18) + d << 0;
    b += (d ^ (a & (c ^ d))) + blocks[4] - 405537848;
    b = (b << 20 | b >>> 12) + c << 0;
    a += (c ^ (d & (b ^ c))) + blocks[9] + 568446438;
    a = (a << 5 | a >>> 27) + b << 0;
    d += (b ^ (c & (a ^ b))) + blocks[14] - 1019803690;
    d = (d << 9 | d >>> 23) + a << 0;
    c += (a ^ (b & (d ^ a))) + blocks[3] - 187363961;
    c = (c << 14 | c >>> 18) + d << 0;
    b += (d ^ (a & (c ^ d))) + blocks[8] + 1163531501;
    b = (b << 20 | b >>> 12) + c << 0;
    a += (c ^ (d & (b ^ c))) + blocks[13] - 1444681467;
    a = (a << 5 | a >>> 27) + b << 0;
    d += (b ^ (c & (a ^ b))) + blocks[2] - 51403784;
    d = (d << 9 | d >>> 23) + a << 0;
    c += (a ^ (b & (d ^ a))) + blocks[7] + 1735328473;
    c = (c << 14 | c >>> 18) + d << 0;
    b += (d ^ (a & (c ^ d))) + blocks[12] - 1926607734;
    b = (b << 20 | b >>> 12) + c << 0;
    bc = b ^ c;
    a += (bc ^ d) + blocks[5] - 378558;
    a = (a << 4 | a >>> 28) + b << 0;
    d += (bc ^ a) + blocks[8] - 2022574463;
    d = (d << 11 | d >>> 21) + a << 0;
    da = d ^ a;
    c += (da ^ b) + blocks[11] + 1839030562;
    c = (c << 16 | c >>> 16) + d << 0;
    b += (da ^ c) + blocks[14] - 35309556;
    b = (b << 23 | b >>> 9) + c << 0;
    bc = b ^ c;
    a += (bc ^ d) + blocks[1] - 1530992060;
    a = (a << 4 | a >>> 28) + b << 0;
    d += (bc ^ a) + blocks[4] + 1272893353;
    d = (d << 11 | d >>> 21) + a << 0;
    da = d ^ a;
    c += (da ^ b) + blocks[7] - 155497632;
    c = (c << 16 | c >>> 16) + d << 0;
    b += (da ^ c) + blocks[10] - 1094730640;
    b = (b << 23 | b >>> 9) + c << 0;
    bc = b ^ c;
    a += (bc ^ d) + blocks[13] + 681279174;
    a = (a << 4 | a >>> 28) + b << 0;
    d += (bc ^ a) + blocks[0] - 358537222;
    d = (d << 11 | d >>> 21) + a << 0;
    da = d ^ a;
    c += (da ^ b) + blocks[3] - 722521979;
    c = (c << 16 | c >>> 16) + d << 0;
    b += (da ^ c) + blocks[6] + 76029189;
    b = (b << 23 | b >>> 9) + c << 0;
    bc = b ^ c;
    a += (bc ^ d) + blocks[9] - 640364487;
    a = (a << 4 | a >>> 28) + b << 0;
    d += (bc ^ a) + blocks[12] - 421815835;
    d = (d << 11 | d >>> 21) + a << 0;
    da = d ^ a;
    c += (da ^ b) + blocks[15] + 530742520;
    c = (c << 16 | c >>> 16) + d << 0;
    b += (da ^ c) + blocks[2] - 995338651;
    b = (b << 23 | b >>> 9) + c << 0;
    a += (c ^ (b | ~d)) + blocks[0] - 198630844;
    a = (a << 6 | a >>> 26) + b << 0;
    d += (b ^ (a | ~c)) + blocks[7] + 1126891415;
    d = (d << 10 | d >>> 22) + a << 0;
    c += (a ^ (d | ~b)) + blocks[14] - 1416354905;
    c = (c << 15 | c >>> 17) + d << 0;
    b += (d ^ (c | ~a)) + blocks[5] - 57434055;
    b = (b << 21 | b >>> 11) + c << 0;
    a += (c ^ (b | ~d)) + blocks[12] + 1700485571;
    a = (a << 6 | a >>> 26) + b << 0;
    d += (b ^ (a | ~c)) + blocks[3] - 1894986606;
    d = (d << 10 | d >>> 22) + a << 0;
    c += (a ^ (d | ~b)) + blocks[10] - 1051523;
    c = (c << 15 | c >>> 17) + d << 0;
    b += (d ^ (c | ~a)) + blocks[1] - 2054922799;
    b = (b << 21 | b >>> 11) + c << 0;
    a += (c ^ (b | ~d)) + blocks[8] + 1873313359;
    a = (a << 6 | a >>> 26) + b << 0;
    d += (b ^ (a | ~c)) + blocks[15] - 30611744;
    d = (d << 10 | d >>> 22) + a << 0;
    c += (a ^ (d | ~b)) + blocks[6] - 1560198380;
    c = (c << 15 | c >>> 17) + d << 0;
    b += (d ^ (c | ~a)) + blocks[13] + 1309151649;
    b = (b << 21 | b >>> 11) + c << 0;
    a += (c ^ (b | ~d)) + blocks[4] - 145523070;
    a = (a << 6 | a >>> 26) + b << 0;
    d += (b ^ (a | ~c)) + blocks[11] - 1120210379;
    d = (d << 10 | d >>> 22) + a << 0;
    c += (a ^ (d | ~b)) + blocks[2] + 718787259;
    c = (c << 15 | c >>> 17) + d << 0;
    b += (d ^ (c | ~a)) + blocks[9] - 343485551;
    b = (b << 21 | b >>> 11) + c << 0;

    if (this.first) {
      this.h0 = a + 1732584193 << 0;
      this.h1 = b - 271733879 << 0;
      this.h2 = c - 1732584194 << 0;
      this.h3 = d + 271733878 << 0;
      this.first = false;
    } else {
      this.h0 = this.h0 + a << 0;
      this.h1 = this.h1 + b << 0;
      this.h2 = this.h2 + c << 0;
      this.h3 = this.h3 + d << 0;
    }
  };

  /**
   * @method hex
   * @memberof Md5
   * @instance
   * @description Output hash as hex string
   * @returns {String} Hex string
   * @see {@link md5.hex}
   * @example
   * hash.hex();
   */
  Md5.prototype.hex = function () {
    this.finalize();

    var h0 = this.h0, h1 = this.h1, h2 = this.h2, h3 = this.h3;

    return HEX_CHARS[(h0 >> 4) & 0x0F] + HEX_CHARS[h0 & 0x0F] +
      HEX_CHARS[(h0 >> 12) & 0x0F] + HEX_CHARS[(h0 >> 8) & 0x0F] +
      HEX_CHARS[(h0 >> 20) & 0x0F] + HEX_CHARS[(h0 >> 16) & 0x0F] +
      HEX_CHARS[(h0 >> 28) & 0x0F] + HEX_CHARS[(h0 >> 24) & 0x0F] +
      HEX_CHARS[(h1 >> 4) & 0x0F] + HEX_CHARS[h1 & 0x0F] +
      HEX_CHARS[(h1 >> 12) & 0x0F] + HEX_CHARS[(h1 >> 8) & 0x0F] +
      HEX_CHARS[(h1 >> 20) & 0x0F] + HEX_CHARS[(h1 >> 16) & 0x0F] +
      HEX_CHARS[(h1 >> 28) & 0x0F] + HEX_CHARS[(h1 >> 24) & 0x0F] +
      HEX_CHARS[(h2 >> 4) & 0x0F] + HEX_CHARS[h2 & 0x0F] +
      HEX_CHARS[(h2 >> 12) & 0x0F] + HEX_CHARS[(h2 >> 8) & 0x0F] +
      HEX_CHARS[(h2 >> 20) & 0x0F] + HEX_CHARS[(h2 >> 16) & 0x0F] +
      HEX_CHARS[(h2 >> 28) & 0x0F] + HEX_CHARS[(h2 >> 24) & 0x0F] +
      HEX_CHARS[(h3 >> 4) & 0x0F] + HEX_CHARS[h3 & 0x0F] +
      HEX_CHARS[(h3 >> 12) & 0x0F] + HEX_CHARS[(h3 >> 8) & 0x0F] +
      HEX_CHARS[(h3 >> 20) & 0x0F] + HEX_CHARS[(h3 >> 16) & 0x0F] +
      HEX_CHARS[(h3 >> 28) & 0x0F] + HEX_CHARS[(h3 >> 24) & 0x0F];
  };

  /**
   * @method toString
   * @memberof Md5
   * @instance
   * @description Output hash as hex string
   * @returns {String} Hex string
   * @see {@link md5.hex}
   * @example
   * hash.toString();
   */
  Md5.prototype.toString = Md5.prototype.hex;

  /**
   * @method digest
   * @memberof Md5
   * @instance
   * @description Output hash as bytes array
   * @returns {Array} Bytes array
   * @see {@link md5.digest}
   * @example
   * hash.digest();
   */
  Md5.prototype.digest = function () {
    this.finalize();

    var h0 = this.h0, h1 = this.h1, h2 = this.h2, h3 = this.h3;
    return [
      h0 & 0xFF, (h0 >> 8) & 0xFF, (h0 >> 16) & 0xFF, (h0 >> 24) & 0xFF,
      h1 & 0xFF, (h1 >> 8) & 0xFF, (h1 >> 16) & 0xFF, (h1 >> 24) & 0xFF,
      h2 & 0xFF, (h2 >> 8) & 0xFF, (h2 >> 16) & 0xFF, (h2 >> 24) & 0xFF,
      h3 & 0xFF, (h3 >> 8) & 0xFF, (h3 >> 16) & 0xFF, (h3 >> 24) & 0xFF
    ];
  };

  /**
   * @method array
   * @memberof Md5
   * @instance
   * @description Output hash as bytes array
   * @returns {Array} Bytes array
   * @see {@link md5.array}
   * @example
   * hash.array();
   */
  Md5.prototype.array = Md5.prototype.digest;

  /**
   * @method arrayBuffer
   * @memberof Md5
   * @instance
   * @description Output hash as ArrayBuffer
   * @returns {ArrayBuffer} ArrayBuffer
   * @see {@link md5.arrayBuffer}
   * @example
   * hash.arrayBuffer();
   */
  Md5.prototype.arrayBuffer = function () {
    this.finalize();

    var buffer = new ArrayBuffer(16);
    var blocks = new Uint32Array(buffer);
    blocks[0] = this.h0;
    blocks[1] = this.h1;
    blocks[2] = this.h2;
    blocks[3] = this.h3;
    return buffer;
  };

  /**
   * @method buffer
   * @deprecated This maybe confuse with Buffer in node.js. Please use arrayBuffer instead.
   * @memberof Md5
   * @instance
   * @description Output hash as ArrayBuffer
   * @returns {ArrayBuffer} ArrayBuffer
   * @see {@link md5.buffer}
   * @example
   * hash.buffer();
   */
  Md5.prototype.buffer = Md5.prototype.arrayBuffer;

  /**
   * @method base64
   * @memberof Md5
   * @instance
   * @description Output hash as base64 string
   * @returns {String} base64 string
   * @see {@link md5.base64}
   * @example
   * hash.base64();
   */
  Md5.prototype.base64 = function () {
    var v1, v2, v3, base64Str = '', bytes = this.array();
    for (var i = 0; i < 15;) {
      v1 = bytes[i++];
      v2 = bytes[i++];
      v3 = bytes[i++];
      base64Str += BASE64_ENCODE_CHAR[v1 >>> 2] +
        BASE64_ENCODE_CHAR[(v1 << 4 | v2 >>> 4) & 63] +
        BASE64_ENCODE_CHAR[(v2 << 2 | v3 >>> 6) & 63] +
        BASE64_ENCODE_CHAR[v3 & 63];
    }
    v1 = bytes[i];
    base64Str += BASE64_ENCODE_CHAR[v1 >>> 2] +
      BASE64_ENCODE_CHAR[(v1 << 4) & 63] +
      '==';
    return base64Str;
  };

  var exports = createMethod();

  if (COMMON_JS) {
    module.exports = exports;
  } else {
    /**
     * @method md5
     * @description Md5 hash function, export to global in browsers.
     * @param {String|Array|Uint8Array|ArrayBuffer} message message to hash
     * @returns {String} md5 hashes
     * @example
     * md5(''); // d41d8cd98f00b204e9800998ecf8427e
     * md5('The quick brown fox jumps over the lazy dog'); // 9e107d9d372bb6826bd81d3542a419d6
     * md5('The quick brown fox jumps over the lazy dog.'); // e4d909c290d0fb1ca068ffaddf22cbd0
     *
     * // It also supports UTF-8 encoding
     * md5('中文'); // a7bac2239fcdcb3a067903d8077c4a07
     *
     * // It also supports byte `Array`, `Uint8Array`, `ArrayBuffer`
     * md5([]); // d41d8cd98f00b204e9800998ecf8427e
     * md5(new Uint8Array([])); // d41d8cd98f00b204e9800998ecf8427e
     */
    root.md5 = exports;
    if (AMD) {
      define(function () {
        return exports;
      });
    }
  }
})();

将其保存到项目中:\PeiQi1\static\js\md5.js

因为在登录,注册,重新修改密码时都会用到Js的加密算法所以我们可以将js加密模块导入到整个用户模块中去.

base_user.html添加:

{% block ext_js %}
{{ block.super }}
    <script type="text/javascript" src="{% static 'js/md5.js' %}"></script>
{% endblock %}

新建login.js:

function parse_data(){
    var $password_input = $('#password_input');
    
    var password = $password_input.val().trim();
    
    $password_input.val(md5(password));
    
    return true
}

login.html:

{% block ext_js %}
{{ block.super }}
    <script type="text/javascript" src="{% static 'peiqi1/user/js/login.js' %}"></script>
{% endblock %}

因为我们在登录的时候使用了md5,所以在注册的时候同样需要添加md5:
register.js:(44-48行)

$(function () {

    var $username = $('#username_input');

    $username.change(function () {
        var username = $username.val().trim();

        /* 判断内容框是否为空,空的就不发送给服务器验证 */
        if (username.length) {
            // 将用户名发送给服务器预校验
            $.getJSON('/peiqi1/checkuser/', {'username': username}, function (data) {
                console.log(data); /* 打印返回的结果 */

                var $username_info = $('#username_info');

                if (data['status'] === 200) { /*如果状态码位200*/
                    $username_info.html('用户名可用').css('color', 'green');
                } else if (data['status'] === 901) { /*如果状态码为901*/
                    $username_info.html('用户已存在').css('color', 'red');
                }
            })
        }
    })
})


    function check() {
        var $username = $('#username_input');

        var username = $username.val().trim();

        if (!username) {
            return false
            /*如果没有数据,就返回false不能注册*/
        }
        /* 判断返回的字的颜色,如果是红色的就返回false,为绿的就返回true */
        var info_color = $('username_info').css('color'); /*返回字体颜色*/

        console.log(info_color);

        if (info_color == 'rgb(255,0,0)') { /*如果返回返回的rgb为255,0,0,那么就返回false */
            return false
        }

        var $password_input = $('#password_input');

        var password = $password_input.val().trim();

        var pwdmd5 = md5(password);

        $password_input.val(pwdmd5);

        console.info(pwdmd5);

        return true
    }

另外我们在登录用户的时候,点击登录按钮的时候密码会变长,其实就是对密码进行了摘要算法处理。

这样我们注册的密码和登录的密码都是进行md5处理之后再上传到服务器中的了。

最后修改:2024 年 03 月 13 日
如果觉得我的文章对你有用,请随意赞赏