弹性布局Flexbox

整   理:晋 哲

时   间:2017-01-06

说   明:使用弹性布局,设置自适应布局、水平垂直居中等样式

弹性布局很早就出来了,但之前一直没有使用Flexbox主要还是考虑兼容性,且兼容性写法太冗余。目前,旧版的属性都已被重新修改,所有浏览器的兼容性也得到很大支持,移动端可以放心使用了,当然浏览器前缀还是要加上的。

能够被运用到的布局结构,如响应式布局、选项卡分布、水平垂直居中等,优先考虑使用flex,代替之前一些特殊布局所使用的传统解决方案:使用display属性或position属性或float属性。

flex常用属性

display:将元素设置为内联或者块flexbox容器元素
flex:复合属性。设置或检索弹性盒模型对象的子元素如何分配空间。
justify-content:控制flex容器内item的水平对齐方式
align-items:控制flex容器内item的垂直对齐方式
flex-direction:定义弹性盒子元素的排列方向

其属性值:

display:flex | inline-flex
flex:none | < flex-grow > | < flex-shrink > | < flex-basis >
justify-content:flex-start | flex-end | center | space-between | space-around
align-items:    flex-start | flex-end | center | baseline | stretch
flex-direction:row | row-reverse | column | column-reverse

常见用法:
一、自适应布局

<!-- HTML -->
<div class="box">
    <div class="subnav"></div>
    <div class="content"></div>
</div>

<!-- CSS -->
.box{
    display: -webkit-box;
    display: -webkit-flex;
    display: flex;
}
.subnav{
    width: 100px;
    height: 100px;
    background: #000;
}
.content{
    background: #f60;
    -webkit-box-flex: 1;
    -webkit-flex: 1;
    flex: 1;
}

解释:subnav固定宽度,content自适应撑满剩余空间

二、使用 Flexbox 的水平垂直居中布局

<!-- HTML -->
<div class="box">
    <div class="content"></div>
</div>

<!-- CSS -->
.box{
    height: 200px;
    background: #eee;
    display: -webkit-box;
    display: -webkit-flex;
    display: flex;
    -webkit-align-items: center;
    align-items: center;
    -webkit-justify-content: center;
    justify-content: center;
}
.content{
    width: 100px;
    height: 100px;
    background: #f60;
}

Sass mixin制作水平垂直居中

整   理:晋 哲

时   间:2017-01-06

说   明:使用Sass mixin 的方式将一些固定样式用法封装起来,能够提高样式复用性。

如水平垂直居中的示例:
常用的水平垂直居中方式是使用CSS transform属性或负向margin的方式,将这两种方法集成起来,通过判断是否有宽高值生成对应的样式。

/*定义mixin*/
@mixin center($width: null, $height: null){
     position: absolute;
     top: 50%;
     left: 50%;

     @if not $width and not $height{
          transform: translate(-50%, -50%);
     }
     @else if $width and $height{
          width: $width;
          height: $height;
          margin: -($height/2) #{0 0} -($width/2);
     }
     @else if not $height{
          width: $width;
          margin-left: -($width/2);
          transform: translate(0, -50%);
     }
     @else{
          height: $height;
          margin-top: -($height/2);
          transform: translate(-50%, 0);
     }
}

/*使用*/
.box1{
     @include center;
}
.box2{
     @include center(200px);
}
.box3{
     @include center(null, 300px);
}
.box4{
     @include center(200px, 300px);
}

CSS3 Animation steps()函数属性运用

整   理:晋 哲

时   间:2017-01-06

说   明:利用steps()函数的特效可以制作类gif动画的动态效果,搭配sprite图使用。

作用优势:代替gif动图的繁琐制作,调整动画便捷,较gif更清晰,图片进行压缩,文件可更小。

使用说明:animation的steps()函数内部的第一个参数设置为正整数,可以计算等分@keyframes规则内from到to的差值,最终进行动画切换。

如示例代码:

.dragon{
    width: 178px;
    height: 188px;
    background: url(images/dragon.png) 0 0 no-repeat;
    animation: run_dragon 2s steps(10) infinite;
}
@keyframes run_dragon{
    0%  {background-position: 0 0;}
    100%{background-position: -1780px 0;}
}

dragon

IOS键盘弹出导致fixed定位错位

整   理:晋 哲

时   间:2017-01-06

说   明:主要是input的焦点事件触发弹出键盘导致fixed定位失效,安卓没有该bug

方法一:使用absolute模拟fixed
1、当触发事件时,将固定定位的元素设置为【position:absolute;top:0;】
若页面高度一屏之内,则事件结束后还原样式即可;若页面很长则继续下一步

2、当页面滚动时,添加滚动事件,更新top值,使其看似一直在顶部

window.onscroll=function(){
    $(".fixed").css("top",$(window).scrollTop());
}

缺点:因为top值时实时计算的,页面滚动时,会有缓冲时间。

方法二:将溢出内容部分设置内部滚动,设置样式【…height:100vh;overflow:auto;】
因为键盘弹出时fixed失效,元素的位置自动根据scrollTop滚动的距离去定位,所以当页面高度为屏幕高度时,系统自动的定位也就在顶部了。

优点:该方法不需要再去设置复杂的js,仅设置样式即可,也是最常用的方法。

缺点:正常情况下是没有问题的,需注意的是商品列表中商品图片使用了lazyload.js,当内容部分设置overflow后,懒加载就失效了,因为它默认是整段body进行滚动监听的。解决方法:lazyload.js有参数【container】可以设置内部框架懒加载的。

解决前:
pic1

解决后:
pic2

网页返回事件监听

一、为什么要监听返回事件
个人中心改版后,用户进入个人中心,从个人中心进入我的资料,在我的资料里面可以修改昵称,头像,邮寄地址等信息。在修改完信息之后,会跳转到我的资料页面,代码中是直接指定了我的资料页面地址。于是,在修改完信息后的我的资料页面点返回按钮,会返回到修改信息的页面,而不会返回到个人中心。如下图历史记录。
image
二、监听返回事件方法
1、监听返回按钮的方法:
window.addEventListener("popstate", function(e) {
alert("我监听到了浏览器的返回按钮事件啦");//根据自己的需求实现自己的功能
}, false);
2、如果这样写,还是会返回到上一页,所以还需要使用pushstate增加一个本页的url。
function pushHistory() {
var state = {
title: "title",
url: "#"
};
window.history.pushState(state, "title", "#");
}
3、完整的写法:
pushHistory();
window.addEventListener("popstate", function(e) {
window.location.href="./wx_grzx.html";
}, false);
function pushHistory() {
var state = {
title: "title",
url: "#"
};
window.history.pushState(state, "title", "#");
}

在实践中,这个方法是会有bug的。如果修改昵称页面不点击保存按钮,直接返回的话会返回到我的资料后立即跳转到个人中心。
于是呢,就出现了使用定时器来解决的方法。
    pushHistory();
    var bool=false;
    setTimeout(function(){
        bool=true;
    },1500);//1.5秒后将bool设置为true
    window.addEventListener("popstate", function(e) {
        if(bool) {
            window.location.href="./wx_grzx.html";
        } else {
            bool = true;//如果在1.5秒内触发了一次,则直接将bool设置为true
        }
        pushHistory();

    }, false);

    function pushHistory() {
        var state = {
            title: "title",
            url: "#"
        };
        window.history.pushState(state, "title", "#");
    }

三、拓展知识
1、popstate用法:
popstate, 是HTML5新标准, 产生的目的就是做客户端前进后退。
每当处于激活状态的历史记录条目发生变化时,popstate事件就会被触发。如果当激活状态的历史记录条目是由history.pushState()方法创建的或者由history.replaceState()方法修改过的,则popstate事件的state属性包含了这条历史记录条目的state对象的一个拷贝。
需要注意的是调用pushState或者replaceState并不会触发popstate事件,只有点击浏览其回退按钮才回触发。

2、pushState和replaceState的异同。
    相同:用法相同
    以pushState来做说明:
    格式:pushState(state, title, url)
    参数说明:
    state:是一个javaScript对象或者json字符串,它关系到由pushState()方法创建出来的新的history实体。用来存储插入到历史记录条目的相关信息。
    title:一个暂时被某些浏览器忽略的参数,不过它在将来可能会被用上。现在的话可以传一个空字符串,也可以传一个简短的标题。
    url:用来传递新的history实体的url。即显示在地址栏的url。
    不同:pushState用于向history添加当前页面的记录,而replaceState是修改当前页面在history中的记录。
3、参考文档
    http://blog.csdn.net/tianyitianyi1/article/details/7426606

四、现有程序中如何使用
现在程序中使用的是,修改信息后,不指定跳转路径,而是使用window.history.go(-1);,这样在修改了信息之后返回到我的资料,我的资料再返就是到个人中心了。

微信公众平台,开放平台等相关基础知识

开放平台
释意:开放互联
平台提供:创建移动应用、创建网站应用、绑定公众帐号、创建公众号第三方平台
核心作用:提供UnionID,可以作为一个userCenter来管理所有渠道汇集过来的微信用户,识别用户唯一性。

一、简要描述和已开放功能
1、移动应用
接入微信开放平台,让你的移动应用支持微信分享、微信收藏和微信支付。
1.1、微信登录
1.2、微信分享与收藏
1.3、微信支付
1.4、微信智能接口(图像识别,语音设别,语音合成,语义理解)
2、网站应用
接入微信开放平台,让你的网站支持使用微信帐号来登录
2.1、微信扫码登录
2.2、微信智能接口(语义理解)
3、绑定公众帐号
接入微信开放平台公众帐号开发,为亿万微信用户提供轻便的服务。
(另翻一篇详说)
4、公众号第三方平台
成为公众号第三方平台,为广大公众号提供运营服务和行业解决方案
(暂无研究)

二、网站应用实践的相关记录
1、创建过程

1.1.1、填写基本信息
附件:微信开放平台网站信息登记表
1.1.2、填写网站信息,即授权回调域
只需要填写域名即可。
1.1.3、提交审核
1.2、据了解,之前起名,不受限制,现在对名字要求严格,尽量保持唯一性。所以对于已经出现过的名字,要求提供证明材料,证明对此名字有绝对的使用权。也许不久的将来,微信也会出一个商标名注册类似的东西吧。。。
1.3、审核提示是7个工作日,实际非常快,两三个小时可能就通过了审核。

2、程序实践
2.1、请求code
2.1.1、跳转方式获取code

2.1.2、jssdk方式获取code





测试网站应用,jssdk方式的登录




2.2、通过code获取access_token
<?php
$appid = 'wx597628e7e8fdbd47'; // 公众平台下,网站应用, 孕期提醒
$appsecret = 'fc02648b9f7698733b0bb45dbe1fcb88';
$state = $_GET['state'];

if ($state != $session_state) {
// die("授权终止");
}
$code = $_GET['code'];

$url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid={$appid}&secret={$appsecret}&code={$code}&grant_type=authorization_code";
$r = curlRequest($url);
var_dump($r);

3、各类功能接口汇总
3.1、请求code
https://open.weixin.qq.com/connect/qrconnect?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE#wechat_redirect
3.2、通过code获取access_token
https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code
3.3、刷新access_token有效期
https://api.weixin.qq.com/sns/oauth2/refresh_token?appid=APPID&grant_type=refresh_token&refresh_token=REFRESH_TOKEN
3.4、检验授权凭证(access_token)是否有效
https://api.weixin.qq.com/sns/auth?access_token=ACCESS_TOKEN&openid=OPENID
3.5、获取用户个人信息(UnionID机制)
https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID

公众平台
释意:微信公众平台是运营者通过公众号为微信用户提供资讯和服务的平台,而公众平台开发接口则是提供服务的基础,开发者在公众平台网站中创建公众号、获取接口权限后,可以通过阅读本接口文档来帮助开发。
平台提供:订阅号,服务号,企业号,小程序
核心说明:微信公众平台开发是指为微信公众号进行业务开发;不要跟开放平台弄混淆。
其他说明,详见官方文档。https://mp.weixin.qq.com/wiki

一、简要描述和已开放、可申请功能 https://mp.weixin.qq.com/wiki
1、权限(开始前必读——公众号接口权限说明)
2、接口测试号申请:http://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=sandbox/login
3、接口在线调试:http://mp.weixin.qq.com/debug/
4、其他先看看官方文档吧。。。。。

二、微信内网页授权登录以及指定内容分享
1、授权登录
https://mp.weixin.qq.com/wiki?action=doc&id=mp1421140842&t=0.46117882231840723#1
2、指定分享内容
https://mp.weixin.qq.com/wiki?action=doc&id=mp1421141115&t=0.9996787578927169#fxjk
关于指定分享内容,之前尝试过,在非绑定域名下调起绑定域名下的资源,指定分享内容,结果是失败了。(有接触过,深究过的,一起探讨下,有没有其他可以绕过去的办法)

之前在专题那边封装的一个微信分享

数据加密技术

目录:
数据加密技术有哪些分类
每个分类的实现方式和常见算法
正文:
一、数据加密技术有哪些分类
对称加密算法
非对称加密算法
单向加密(散列算法)
散列算法不是加密算法, 因为如果目的是加密,必须满足的一个条件是加密过后可以解密。但是散列算法是无法从结果还原出原始数据的。
二、每个分类的实现方式和常见算法
对称加密算法
1、定义:
对称加密算法是应用较早的加密算法,技术成熟。在对称加密算法中,数据发信方将明文(原始数据)和加密密钥一起经过特殊加密算法处理后,使其变成复杂的加密密文发送出去。收信方收到密文后,若想解读原文,则需要使用加密用过的密钥及相同算法的逆算法对密文进行解密,才能使其恢复成可读明文。在大部分对称加密算法中,使用的密钥只有一个,发收信双方都使用这个密钥对数据进行加密和解密,这就要求解密方事先必须知道加密密钥。
在PHP中也有封装好的对称加密函数:Urlencode/Urldecode base64_encode()/base64_decode()
严格的来说,这两个函数其实不算是加密,更像是一种格式的序列化。
2、常见的加密算法:
DES(Data Encryption Standard):数据加密标准,速度较快,适用于加密大量数据的场合。
3DES(Triple DES):是基于DES,对一块数据用三个不同的密钥进行三次加密,强度更高。
AES(Advanced Encryption Standard):高级加密标准,是下一代的加密算法标准,速度快,安全级别高;据说是要取代DES

3、DES算法:
对称加密算法中最经典的算法莫过于DES加密算法。DES加密采用的是分组加密的方法,使用56位密钥加密64位明文,最后产生64位密文。DES算法的基本流程如下图所示。

现在对图的整个流程做简要的分析。DES对64位的明文分组M进行操作,M经过一个初始置换IP置换成m0,将m0明文分成左半部分和右半部分m0=(L0,R0),各32位长。然后进行16轮完全相同的运算,这些运算称为函数f,在运算过程中,数据与密匙结合。经过16轮运算之后,可以看到第16轮运算,将右侧第15轮运算的结果(R15)作为左侧运算的最终结果(L16),而右侧最后的结果(R16)为左侧第15轮运算结果(L15)和函数f运算结果的异或运算所得。此后,再将左、右部分合在一起经过一个逆置换,输出密文。
实际加密过程要分成两个同时进行的过程,即加密过程和密钥生成过程,如下图所示。

如上图所示,在16轮循环的每一轮中,密匙位移位,然后再从密匙的64位中选出48位。通过一个扩展置换将数据的右半部分扩展成48位,并通过一个异或操作替代成新的32位数据,在将其置换一次。这四步运算构成了图1中的函数f。然后,通过另一个异或运算,函数f的输出与左半部分结合,其结果成为新的右半部分,原来的右半部分成为新的左半部分。该操作重复16次。
DES算法的解密过程和加密过程几乎完全相同,只是使用密钥的顺序相反。

4、优缺点
优点:算法公开、加密解密的速度比较快,适合数据比较长时的使用。
缺点:
1、加密方和解密方使用同一个密钥,安全性得不到保障。
2、密钥传输的过程不安全,且容易被破解,每对用户每次使用对称加密算法时,都需要使用其他人不知道的惟一钥匙,这会使得发收信双方所拥有的钥匙数量呈几何级数增长,密钥管理成为用户的负担。对称加密算法在分布式网络系统上使用较为困难,主要是因为密钥管理困难,使用成本较高。

非对称加密算法
1、定义:
与对称加密算法不同,非对称加密算法需要两个密钥:公开密钥(publickey)和私有密钥(privatekey)。公开密钥与私有密钥是一对,如果用公开密钥对数据进行加密,只有用对应的私有密钥才能解密;如果用私有密钥对数据进行加密,那么只有用对应的公开密钥才能解密。因为加密和解密使用的是两个不同的密钥,所以这种算法叫作非对称加密算法。
2、常见的加密算法:
RSA:由 RSA 公司发明,是一个支持变长密钥的公共密钥算法,需要加密的文件块的长度也是可变的;
DSA(Digital Signature Algorithm):数字签名算法,是一种标准的 DSS(数字签名标准);
ECC(Elliptic Curves Cryptography):椭圆曲线密码编码学。

3、http://www.cnblogs.com/zfxJava/p/5295957.html理解公钥和私钥(划重点)

4、优缺点
优点:对称加密算法不能实现签名,因此签名只能非对称算法。比对称加密算法更加安全。
缺点:
1、由于非对称加密算法的运行速度比对称加密算法的速度慢很多,当我们需要加密大量的数据时,建议采用对称加密算法,提高加解密速度。
2、公钥传输的过程不安全,易被窃取和替换,由此产生了数字证书。

单向加密(散列算法)
1、定义:
属于摘要算法(哈希/散列算法),不是一种加密算法,作用是把任意长的输入字符串变化成固定长的输出串的一种函数。加密性强的散列一定是不可逆的,这就意味着通过散列结果,无法推出任何部分的原始信息。任何输入信息的变化,哪怕仅一位,都将导致散列结果的明显变化,这称之为雪崩效应。散列还应该是防冲突的,即找不出具有相同散列结果的两条信息。具有这些特性的散列结果就可以用于验证信息是否被修改。
2、常见的散列算法:
1、MD5(Message Digest Algorithm 5):是RSA数据安全公司开发的一种单向散列算法,非可逆,相同的明文产生相同的密文。
2、SHA(Secure Hash Algorithm):可以对任意长度的数据运算生成一个160位的数值;

3、MD5加密注意点:

md5()为单向加密,没有逆向解密算法,但是还是可以对一些常见的字符串通过收集,枚举,碰撞等方法破解;所以为了让其破解起来更麻烦一些,所以我们一般加一点盐值(salt)并双重MD5;
例: md5(md5($password).'ylcf')
ylcf就是盐值。
4、特点
雪崩效应、定长输出和不可逆。

vueJs父子组件通信以及vue-resource的使用

整   理:晋 哲

时   间:2017-01-03

说   明:实例展示vueJs如何调取数据

一、父子组件基本代码块

/* 父组件 */
<div id="product_list">
    <nav-item></nav-item>
</div>

/* 子组件模块 */
<template id="nav-model">
    ……
</template>

/* 子组件对象 */
Vue.component('nav-item', {
    template: '#nav-model',
    ……
});

/* 主体构造器 */
var ins = new Vue({
    el: '#product_list',
    data: [
        ……
    ],
});

二、父子组件自定义事件,用于在组件树中通信
使用 $on() 监听事件;
使用 $emit() 在它上面触发事件;
使用 $dispatch() 派发事件,事件沿着父链冒泡;
使用 $broadcast() 广播事件,事件向下传导给所有的后代。

三、常用父子组件通信方式
1、父组件向子组件传递数据
使用 Props 传递数据

2、子组件向父组件传递数据
使用 $on() 监听事件;
使用 $emit() 在它上面触发事件。

四、vue-resource的使用(在一个Vue实例内使用$http)
1、GET请求
this.$http.get('/someUrl', [options]).then(successCallback, errorCallback);

2、POST请求
this.$http.post('/someUrl', [body], [options]).then(successCallback, errorCallback);

参考网址:
http://vuejs.org.cn/guide/components.html#使用-v-on-绑定自定义事件
http://www.doc00.com/doc/1001004eg

实例代码请看源代码
vue实例-保险列表

01背包问题基础

编 写: zhangyue
时 间: 2016-12-27
说 明: 利用背包问题解决红包使用问题

一 01背包问题

    01背包问题是指在一个容量大小固定为M的背包中,装入体积和价值不同的宝石,怎么选择才能在背包中得到最大的价值。

二 动态规划

动态规划是指
        通过拆分问题,定义问题状态和状态之间的关系,使得问题能够以一种循环的方式去解决。
        通常基于一个递推公式和一个或多个初始状态,当前子问题的解由上一个子问题的解推出。
        有一类活动的过程,由于它的特殊性,可将过程分成若干个互相联系的阶段,在它的每一阶段都需要作出决策,从而使整个过程达到最        好的活动效果。当然,各个阶段决策的选取不是任意确定的,它依赖于当前面临的状态,又影响以后的发展,当各个阶段决策确定后,就组成一个决策序列,因而也就确定了整个过程的一条活动路线
        
        状态转移方程:
            d(N,M) = max(d(N-1,M), d(N-1, M-weight(i)) + value(i));
            d(N,M) 有容量为M的背包,有N个宝石
            d(N-1,M) 当前的宝石不放入背包,所能获取的最大价值
            d(N-1, M-weight(i)) + value(i) 当前宝石放入背包,所能够获取的最大价值

三 代码

function getResult($bagItems, $bagSize) {
        var result = array();
        //生成状态数组
        foreach ($i = 0; $i < $bagSize; $i ++) {
            foreach ($j = 0; $j < count($bagItems); $j ++) {
                if ($bagItems[$j]['weight'] > $i) {
                    //当前重量大于当前背包总重量
                    if (j != 0) {
                        $result[$j][$i] = $result[$j-1][$i];
                    } else {
                        //第一个元素 $j-1不存在,不存在前一个状态
                        $result[$j][$i] = 0;
                    }
                } else {
                    //当前重量小于背包,可以放入背包
                    if ($j != 0 ) {
                        $tmp_value = $result[$j-1][$i - $bagItems[$j]['weight']] + $bagItems[$j]['weight'];
                        $result[$j][$i] = max($result[$j-1][$i], $tmp_value);
                    } else {
                        //第一个元素 $j-1不存在,不存在前一个状态
                        $result[$j][$i] = $bagItems[$j]['weight'];
                    }
                }
            }
        }

        //根据得到的状态得到所选的数组
        $return  = array();//存储放回的组合
        $cur_size = $bagSize;//当前红包容量
        for ($n = count($bagItems); $n >= 0 ; $n--) {
            if ($cur_size == 0) {
                break;
            } 

            if ($n == 0 && $bagItems[$n]['weight'] < $cur_size) {
                $return[] = $bagItems[$n]['id'];
                break;
            }

            if ($bagItems[$n][$cur_size] - $bagItems[$n-1][$cur_size - $bagItems[$n]['weight']] == $bagItems[$n]['weight']) {
                //判断当前的这个商品是不是在最优解里,如果不在则不放入
                $return[] = $bagItems[$n]['id'];
                $cur_size = $cur_size - $bagItems[$n]['weight'];
            }
        }

        //得到结果
        return $return;

    }

四 递推表格

函数得到的递推表格和最终最优结果:
体积 价值 0 1 2 3 4 5 6 7 8 9 10 11
4 4 0 0 0 0 4 4 4 4 4 4 4 4
5 5 0 0 0 0 4 5 5 5 5 9 9 9
6 6 0 0 0 0 4 5 6 6 6 9 10 11
解释: 1 表格是从上到下,即4-6,从左到右,即0-11生成的 2 第一行的意思:代表在0-11的背包容量下,只有一个体积为4价值为4的宝石时,所能获得最大容量 3 第二行的意思:代表在0-11的背包容量下,有一个体积为4价值为4和体积为5价值为5的两块宝石时,所能获得最大容量 4 第三行的意思:代表在0-11的背包容量下,有一个体积为4价值为4,体积为5价值为5,体积为6价值为6的三块宝石时,所能获得最大容量 5 最终结果:[6,11] = 11 这个最优解。

五 红包问题

使用红包时,只需要将价值和体积都类比于红包的金额即可,这样可以选出最后得到的红包使用组合。
存在问题:
    1 红包会涉及小数的问题,红包现在只保留两位小数,最简单的方法是给红包*100,这样会增加递推数组的大小,增加空间复杂度
    2 红包还存在过期时间,可考虑如何加上过期时间这一条件
    3 由于红包价格和体积是同一个值,可考虑简化算法

用户系统演进

用户系统演进.ppt

编   写:袁 亮
时   间:2016-12-21
说   明:用户系统演进

一、用户系统限制因素
    1、使用域名
        单个域名
        多个域名
    2、使用系统是单服务器还是多服务器
    3、使用域名是否属于同一个域名的不同子域名
    4、系统访问环境
        PC浏览器
        是否兼容IE浏览器
        是否兼容手机浏览器
    5、用户数据库是否唯一
        单一用户数据库
        多个用户数据库
        
二、单用户中心,单域名
    1、条件限制
        1.1 单个域名
        1.2 单一用户数据库
    2、实现方案
        2.1 session
            磁盘IO 
            多服务器session共享
        2.2 cookie
            域名,端口,路径,cookie名
            数据签名
            大小限制
            敏感信息
    3、其他
        3.1 可以有多种登陆方式
        3.2 可以接入很多种第三方登陆
        
三、单用户中心,单个根域名
    1、条件限制
        1.1 单个用户数据库
        1.2 多个域名同属于某个根域名
    2、实现方案
        2.1 cookie共享 (育儿网)
            a. cookie设置在根域名
            b. 所有子域名都可以正常读取并验证签名
            c. 不可扩展,安全性无保障
        2.2 token形式 (共享session机制的变种)
            a. cookie设置在根域名
            b. 子域名读取到cookie之后,调用用户中心接口获取用户数据
            c. 将用户数据写入当前域名下
            
四、单用户中心,多个根域名
    1、条件限制
        1.1 单个用户数据库
    2、实现方案
        2.1 单点登陆 jsonp方式跨域 (淘宝)
            a. 统一的登陆,查收ticket
            b. jsonp方式将ticket循环传递给所有业务
            c. 业务域名根据ticket获取用户信息设置登陆
            d. 退出同样方式处理
            缺点:
                ios下,浏览器默认禁止第三方域名cookie设置,直接歇菜
        2.2 单点登陆 cas方式 (新浪)
            a. 通过jsonp+ajax+iframe的方式,在各个子域名框用户中心登陆
            b. 
            缺点:手机浏览器对iframe支持的很差
        2.3 服务端ticket形式,jsonp形式单点登录的变种
        
五、多用户中心
    1、条件限制
        无
    2、实现方案
        2.1 单域名或者多根域名跨域同三和四
    3、额外增加处理
        3.1 统一跳转地址
        3.2 用户聚合统一
        3.3 平台信息维护
        3.4 vtoken登录