登录功能
上一篇文章,我们完善了注册的功能。这一次完善登录功能。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处理之后再上传到服务器中的了。
此处评论已关闭