一、app视图与控制器
1)路由
这里的v1、v2就是模块,由于客户端版本一直在迭代的,那么一些老版本的客户端调用的接口就得保留起来,使得兼容。新版本就直接调用新接口。
还有一种是写html页面,在客户端展示,只要把template文件夹和data文件夹加上就可以了。
Controller的配置如下,注意ismodule是true,module_list中的array:
$InitPHP_conf['ismodule'] = true; //开启module方式
$InitPHP_conf['controller']['path'] = 'controller';$InitPHP_conf['controller']['controller_postfix'] = 'Controller'; //控制器文件后缀名
$InitPHP_conf['controller']['action_postfix'] = ''; //Action函数名称后缀
$InitPHP_conf['controller']['default_controller'] = 'index'; //默认执行的控制器名称
$InitPHP_conf['controller']['default_action'] = 'index'; //默认执行的Action函数
$InitPHP_conf['controller']['module_list'] = array('v1','v2'); //module白名单
$InitPHP_conf['controller']['default_module'] = 'v1'; //默认执行module
$InitPHP_conf['controller']['default_before_action'] = 'before'; //默认前置的ACTION名称
$InitPHP_conf['controller']['default_after_action'] = 'after'; //默认后置ACTION名称
这里顺便说下
1.原生模式:index.php?c=index&a=run
2.rewrite模式:/index/run/id=1 (需要开启服务器rewrite模块,并且配置.htaccess)
3.path模式:/index/run/id/1 (需要开启服务器rewrite模块,并且配置.htaccess)
4.html模式: user-index-run.htm?uid=100 (需要开启服务器rewrite模块,并且配置.htaccess)
2)模拟session
这里模拟的方法比较简单而粗暴。
在登录的时候,会生成一串字符,然后保存到用户表中,这串字符会返回给客户端,作为session。
在登录后客户端会将这串字符传过来,服务器再根据这串字符在搜索用户,从未获取用户信息,并判断是否已经登录。
二、apiController通用控制器类
public function__construct() {
parent::__construct();$this->controller_name = $this->getC();$this->action_name = $this->getA();$this->module_name = $this->getM();//访问参数日志记录
$this->_logVisit();//API统一接口为post提交
if (!$this->controller->is_post()) {$this->output(constHelper::API_STATUS_NEED_POST, '必须为POST请求');
}/**
* 请求参数示例
* __ua=Android 4.4.4//MI 3W//26//2.0//865645022129866//WIFI&
* __timestamp=1441854121116&
* mobile=13800138000&
* __version=2.0&
* __device=android&type=2&
* __key=67543fd413ce4d281fc93306597acb66*/
$device = $this->p('__device'); //客户端名称
$timestamp = $this->p('__timestamp'); //客户端时间戳
$key = $this->p('__key'); //客户端加密指纹
$session = $this->p('__session'); //客户端SESSION
$version = substr($this->p('__version'), 0, 5); //客户端版本
//客户端最低版本号要求
if (strnatcmp($version, constHelper::MIN_VERSION_ALLOWED) < 0) { //客户端需要升级
$this->output(constHelper::API_STATUS_NEED_UPGRADE, '客户端需要升级');
}//检查密钥
$this->_checkSecretKey($device, $timestamp, $key);//判断是否需要验证登录
$needCheck = $this->_checkLogin();if($needCheck && empty($session)) {$this->output(constHelper::API_STATUS_NEED_LOGIN, '请先登录');
}//根据session获取用户信息
if(!empty($session)){$memberModel = InitPHP::getMysqlDao('member');$this->member = $memberModel->getMemberBySession($session);
}//session没有获取到相关信息 也要做跳转
if($needCheck && empty($this->member)) {$this->output(constHelper::API_STATUS_NEED_LOGIN, '请先登录');
}
}
1)访问参数日志记录
当客户端发起一个请求的时候,会带上很多参数,例如操作系统、当前版本号、时间戳、口令、网络、应用市场等信息。
调用$this->_logVisit();将这些信息全部存到MongoDB中,便于以后调试与追踪。并且在返回参数的时候,将返回参数更新到这条请求记录中。
2)output返回参数
返回参数的格式如下:
{"code":1000,
"msg":"hello\u6210\u529f",
"data":{"result":1,
"obj":{"id":"55f57a4aa0105"}
}
}
code:是各种通用的错误编码,我写在了libraray/helper/dict/constHelper中,如上面的代码所示,当验证出现错误的时候,会显示响应的code,并返回
msg:就是提示语言,这里做了Unicode编码
data:返回的就是各种自定义参数,这里仅列举了通用的两种
result:也是类似于code的定义,不同的是针对的是特定请求中的返回码
obj:返回的就是个自定义对象,也可以是数组
3)密钥匹配
为了保证请求的合法性,在客户端和服务器端约定一个密钥,客户端在根据这个密钥做加密后,传过来给服务器端,服务端再加密然后做匹配。
服务器端将密钥设置在defined文件中,IOS,Android可以定义的不同:
define('API_IOS_KEY', 'DF_A98=D^&7$^%*9CNAhj0UO!!LM11');define('API_ANDROID_KEY', 'KU98&)dsf8%@kji89dfadJK-800i122');define('API_UNKNOW_KEY', 'jfdsfd798hj+@(*kb66578-223q670933');
而验证的规则也很简单,时间戳+密钥再MD5加密:
private function _checkSecretKey($device, $timestamp, $key) {//提取私有密钥
$privateKey = '';switch (strtolower($device)) {case 'ios':
$privateKey =API_IOS_KEY;break;case 'android':
$privateKey =API_ANDROID_KEY;break;default:
$privateKey =API_UNKNOW_KEY;break;
}$keySource = $privateKey . $timestamp;//客户端安全认证失效
if (empty($key) || ($key != md5($keySource))) {$this->outputCom(constHelper::API_STATUS_AUTH_FAIL, '安全认证失败');
}
}
4)各种验证
1.第一个验证是只接收post请求,这里直接使用了
2.客户端最低版本号验证,有时候客户端需要强制升级
3.登录验证,这里有多种情况,有些API是不需要登录的,有些是需要登录的,而有些是既可以登录也可以不登录
三、API调试工具
在交付给客户端之前,自己肯定要先测试一下的,这就需要一个简易工具了,当然也可以选择一些强大的工具,例如firefox的httprequester等。
在tool文件夹下面,我已经把这个工具放在里面了,执行页面如下:
工具的文件目录也很淳朴,就五个文件,有两个地方需要配置:
1)在indexhtml中data-domain属性,修改为你当前的api域名,在第13行左右
2)在tk.php中,修改数据库连接参数,以及客户端密钥
GitHub地址: