Auth的原理网上有很多,我这里就不在赘述了。
这里有张时序图我个人觉得是比较合理而且直观的,(感谢这篇博文:http://justcoding.iteye.com/blog/1950270)
参照这个流程,模拟了下部分代码,当然是尽可能的以简单的形式去表达下自己的见解
模拟了配置文件去掉数据库处理的部分
config.php 定义了公司及对应的操作用户的权限
<?php return array('app'=>array('a1'=>array('accesskey'=>'123456',//凭证'type'=>0,//聚合这里规定type对应的请求权限'appname'=>'gavinjun',),),'type'=>array(array('获取用户的信息','获取用户的金钱',),), );
user_config.php 用户表的模拟
<?php return array('admin'=>'123456', );
<?php //权限2.0的主程 class Auto{private $vession=2.0;private $notic=null;public function __construct(){$notic = require 'config.php';$this->notic = $notic;}//校验商户public function check($_param=array()){if(empty($_param)){return false;}//获取传过来的accesskey appid$appid = !empty($_param['appid'])?$_param['appid']:0;$accesskey=!empty($_param['accesskey'])?$_param['accesskey']:'';if(!$appid||!$accesskey)return false;//校验开始$notic = $this->notic;return $notic['app'][$appid]?$notic['app'][$appid]['accesskey']==$accesskey:false;}//用户发起登录请求public function getLoginCallBack($_param){if($this->check($_param)){//校验通过返回临时的token 以下都是不安全的方式只是模拟auto的流程//这里可以用加密 请求时间|请求完成后跳转地址|用户的md5(accesskey)return time().'|'.$_param['redirect'].'|'.md5($_param['accesskey']).'|'.$_param['appid'];}else{echo '商户未注册';return false;}}//用户输入完用户名和密码之后public function inLogin($name,$pwd){$user = require("user_config.php");return $user[$name]?$user[$name]==$pwd:false;}//用户登录完成后带着token值来请求我们的令牌public function getAceess($_param){$token = $_param['access_token'];if(!$token)return false;list($time,$redirect,$authkey,$appid) = explode('|',$token);//请求$appid 获取他的accesskey$notic = $this->notic;$accesskey = $notic['app'][$appid]['accesskey'];if(time()>$time+5*60){//超过5分钟才请求默认失败return false;}if(md5($accesskey)!=$authkey){//链接不安全return false;}//返回正式的key//这个key可以保存在数据库中设置这个key的失效时间 //我这里随便固定了他的accesskey//给跳转的页面发送一个key 用post的应该,不过模拟就算了$access = 'success';return $redirect.'?access='.$access;}public function doSomeByaccess($access){//和数据库中做比对 这里不写了,就全部默认成功if($access){$appid = 'a1';}$notic = $this->notic;$type = $notic['app'][$appid]['type'];foreach($notic['type'][$type] as $v){echo '用户权限:'.$v.'<br>';}} }
这里是模拟下这段程序的流程
<?php //模拟流程 require 'auth2.php'; $auth2= new Auto();//step 1: 用户点击平台上的登录按钮 //该商户的信息 appid=a1,accesskey=123456 $step1=$auth2->getLoginCallBack(array('appid'=>'a1','accesskey'=>'123456','redirect'=>'http://www.baidu.com')); //系统内部跳转到登录界面拿到临时token 让用户去登录授权 $access_token = $step1; /**系统内部的处理流程***/ //系统跳到登录地址?access_token=$step1 用户输入用户名和密码 //模拟用户授权 if($auth2->inLogin('admin','123456')){//用户同意登录返回了一个令牌$access_token是用户登录请求的时候带上的$arr['access_token']=$access_token;$url = $auth2->getAceess($arr);//这个url会发送给平台,平台拿到这个 令牌可以去访问用户信息echo $url; } /****系统内部处理结束跳转到用户平台地址,发送post信息****/ //假设平台接到这个信息他保存下来了这个accesskey,去读取一遍用户的信息 $url = parse_url($url); list($access,$accesskey)=explode('=',$url['query']); $auth2->doSomeByaccess($accesskey);
结果: