发表日期: 2021-04-26 09:25:55 浏览次数:120
如皋微信公众号开发【如皋网络推广】如皋建站、如皋网站维护、如皋网页制作、如皋微信小程序代运营公司
如皋市,简称“如”或“皋”,江苏省辖县级市,由南通市代管,江苏省历史文化名城。地处长江三角洲北翼,位于南通、泰州、苏州三市交界处,南与张家港市隔江相望,北与海安市、东与如东县连接、东南与南通市通州区毗邻,西与泰兴市、西南与靖江市接壤。全市总面积1477平方公里(不含长江水面),长江水面99平方千米。如皋长江岸线全长48千米,可直接利用长江深水岸线18.6千米。
如皋市被国际自然医学会评为世界六大长寿乡之一。 [1] 如皋市户籍人口约142万。截至2021年1月1日,全市80周岁以上高龄老人68031人,90周岁以上高龄老人10150人,百岁老人达525位,其中105岁以上达16位。 [2]
2019年6月17日,如皋被中华人民共和国住房和城乡建设部选取作为开展规范城市户外广告设施管理工作试点城市。 [3] 2019年10月8日,被评为2019年度全国综合实力百强县市、2019年度全国绿色发展百强县市、2019年度全国新型城镇化质量百强县市、2019全国营商环境百强县。 [4-6] 2020年12月,社科院发布《全国县域经济综合竞争力100强》,如皋排名第31 [7] 。
正如前面所说,项目应该实现自己专属的签名方案,以识别是合法的接口请求。当需要实现签名验证时,只需要简单的两步即可:
第1步、实现过滤器接口PhalApi_Filter::check()
第2步、注册过滤器服务DI()->filter
现以大家熟悉的微信公众号开发平台的验签为例,进行说明。
微信的加密/校验流程如下:
1、 将token、timestamp、nonce三个参数进行字典序排序
2、将三个参数字符串拼接成一个字符串进行sha1加密
3.、开发者获得加密后的字符串可与signature对比,标识该请求来源于微信
参考:以上内容摘自接入指南 - 微信公众平台开发者文档。
首先,需要实现过滤器接口PhalApi_Filter::check()。通常我们约定返回ret = 402时表示验证失败,所以当签名失败时,我们可以返回ret = 402以告知客户端签名不对。根据微信的检验signature的PHP示例代码,我们可以快速实现自定义签名规则,如:
//$ vim ./Shop/Common/Request/WeiXinFilter.php<?phpclass Common_Request_WeiXinFilter implements PhalApi_Filter {
public function check() {
$signature = DI()->request->get('signature');
$timestamp = DI()->request->get('timestamp');
$nonce = DI()->request->get('nonce');
$token = 'Your Token Here ...'; // TODO
$tmpArr = array($token, $timestamp, $nonce);
sort($tmpArr, SORT_STRING);
$tmpStr = implode($tmpArr);
$tmpStr = sha1( $tmpStr );
if ($tmpStr != $signature) {
throw new PhalApi_Exception_BadRequest('wrong sign', 1);
}
}}复制代码随后,我们只需要再简单地注册一下过滤器服务即可,在对应项目的入口文件index.php中添加:
//$ vim ./Public/shop/index.php // 微信签名验证服务DI()->filter = 'Common_Request_WeiXinFilter';复制代码
当我们再次请求接口时,此时的签名方案就会从原来默认的md5加密算法切换到这个新的签名验证方案上。实现的要点是,当签名失败时,抛出401错误码。而异常类PhalApi_Exception_BadRequest表示客户端非法请求,其异常码的基数是400,所以第二个构造函数参数传1即可。
对于接口响应,PhalApi默认使用了HTTP+JSON。通过HTTP/HTTPS协议进行通讯,返回的结果则使用JSON格式进行传递。正常情况下,当接口服务正常响应时,如前面的Hello World接口,可能看到以下这样的响应头部信息和返回内容。
HTTP/1.1 200 OKContent-Type: application/json;charset=utf-8... ...{"ret":200,"data":"Hello World","msg":""}复制代码而当接口项目抛出了未捕捉的异常,或者因PHP语法问题而出现Error时,则没有内容返回,并且得到一个500的响应状态码。类似如下:
HTTP/1.1 500 Internal Server Error复制代码
若运行环境中PHP的display_errors配置为On时,还是会返回200的,并直接显示错误信息。在生产环境上,则切记需要把display_errors设置为Off。
下面,我们将重点学习正常响应情况下的响应结构和返回格式,在线调试以及异常情况下如何进行问题排查与定位。
继续来回顾一下默认接口服务返回的内容。类似如下:
{
"ret": 200,
"data": {
"title": "Hello World!",
"content": "PHPer您好,欢迎使用PhalApi!",
"version": "1.4.0",
"time": 1492776704
},
"msg": ""}复制代码ret字段是返回状态码,200表示成功;data字段是项目提供的业务数据,由接口开发人员定义;msg是异常情况下的错误提示信息。下面分别说之。
业务数据data为接口和客户端主要沟通对接的数据部分,可以为任何类型,由接口开发人员定义定义。但为了更好地扩展、向后兼容,建议都使用可扩展的集合形式,而非原生类型。也就是说,应该返回一个数组,而不应返回整型、布尔值、字符串这些基本类型。所以,Hello Wolrd接口服务返回的数据类型是不推荐的,因为返回的是整型。
业务数据主要是在Api层中返回,即对应接口类的方法的返回结果。如下面的默认接口服务?service=Default.Index的实现代码。
// $ vim ./Shop/Api/Default.php<?phpclass Api_Default extends PhalApi_Api {
... ...
public function index() {
return array(
'title' => 'Hello World!',
'content' => T('Hi {name}, welcome to use PhalApi!', array('name' => $this->username)),
'version' => PHALAPI_VERSION,
'time' => $_SERVER['REQUEST_TIME'],
);
}复制代码实际上,具体的业务数据需要一段复杂的处理,以满足特定业务场景下的需要。后面我们会对如何开发接口服务和使用数据库、高效缓存再进行讨论讲解。这里暂且知道接口结果是在Api层返回,对应接口类成员方法返回的结果即可。
