23.3 接口的安全控制规范

23.2节的示例实现了一个简单接口,但是这个接口此时是在“裸奔”的。因为这个接口所有人都可以请求,不仅我们的客户端可以正常访问数据,如果有人使用如fiddler、wireshark等抓包工具,就很容易获取这个API地址,可以随意地请求获取或篡改我们的数据,这很显然是不安全的。因此,在设计接口时必须加上安全控制这一环节。

23.3.1 API安全控制原则

由于Web API是基于互联网的应用,因此对安全性的要求远比在本地访问数据库严格得多。一般通用的做法是,采用参数加密签名方式传递,即在传递参数时,增加一个加密签名,在服务器端验证签名内容,防止被篡改。对一般的接口访问,只需要使用用户身份的token进行校验,只有检查通过才允许访问数据。API常用的安全控制原则有以下几种:

(1)使用用户名密码。这种方式比较简单,可以有效识别用户的身份(如用户信息、密码,或者相关的接口权限等)。验证成功后,返回相关的数据。

(2)使用安全签名。这种方式提交的数据,URL的连接参数是要经过一定规则的安全加密的,服务器收到数据后也经过同样的规则进行安全加密,确认数据没有被中途篡改后,再进行数据的修改处理。因此,我们可以为不同客户端,如Web、App等不同接入方式指定不同的密钥,但是密钥是双方约定的,并不在网络连接上传输,连接传输的一般是接入的“key”,服务器通过这个“key”来进行签名参数的加密对比。目前,微信后台的回调处理机制,采用的就是这种方法。

(3)公开的接口调用,不需要传入用户令牌,或者对参数进行加密签名,这种接口一般较少,只是提供一些很常规的数据显示而已。

23.3.2 API安全控制简单实现步骤

API的安全控制方法有很多,可以根据项目自身的情况定制一些方法,也可以借鉴一些大的平台处理接口的算法。本节通过一些简单的控制方式,来一步步实现API的安全访问控制。

1.增加时间戳参数

首先,我们在API的URL中添加一个时间戳参数,如“timestamp”,要求请求的客户端在请求接口的时候必须添加此参数。如果在请求的时候没有该参数,就不返回数据。另外,通过时间戳参数,也可以限制请求接口必须要在某个时间段内完成,即便有人发现了接口地址,也只能使用一段时间。加入时间戳参数后,请求接口的URL地址格式如下所示:

https://localhost/userapi.php?id=1&timestamp=1519552181

修改上例中的userclient.php文件,分别使用get()方法请求两次userapi.php接口,一次在URL加上“timestamp”参数,一次不加该参数。修改后代码片段如下所示:

同样地,修改userapi.php接口文件,判断在请求接口时,请求的URL中是否带有“timestamp”参数,并且限制该URL只能在5分钟内有效。修改后的代码片段如下所示:

运行的结果如图23-8所示。

图23-8 测试请求API的URL参数带有时间戳的结果

虽然我们实现了客户端软件在请求API时需要添加“timestamp”参数才能获取数据,但这样依然不能防止别人获取我们的数据,因为通过抓包工具依然是可以看到地址的,所以别人也可以添加 “timestamp”参数请求我们的接口。限时访问也只能瞒得过一般的程序员,稍微细心的程序员就会发现这个规律,他可以生成当前的时间戳,然后模拟参数发送请求来获取数据。

2. 增加签名参数

在发送API调用请求时,为了确保客户端应用与API服务器之间的安全通信,防止盗用URL、数据篡改等恶意攻击行为,在API验证规则中可以使用参数签名机制。过程是客户端应用在调用API之前,需要通过算法计算一个加密的签名,并追加到请求参数中,参数名可以为“sign”。API服务器在接收到请求时,使用同样的算法重新计算签名,并判断其值是否与应用传递来的“sign”参数值一致,以此判定当前API调用请求是否是被第三方伪造或篡改的。

签名的算法很多,本节模拟支付宝的签名算法。例如,制定一个规则,将所有URL的参数提取出来,然后根据参数名进行排序,再将排序后的数组拼接成字符串,最后对该字符串进行 md5或sha1加密(建议使用sha1)后得到“sign”。例如,当前我们的URL 如下所示:

http://localhost/userapi.php?id=1&timestamp=1527068730

(1)得到参数数组:['timestamp'=> 1527068730, 'id'=>100]。

(2)键名根据 ASCII 码进行排序后:['id'=>100, 'timestamp'=> 1527068730]。

(3)组合成字符串:id=100timestamp=1527068730。

(4)使用sha1()函数加密得到fd8cc3348652b9cbf2714689ab7ee9105da67cf4。

客户端和API服务器端签名的计算方法相同,计算后的请求URL地址如下所示:

http://localhost/userapi.php?id=1&timestamp=1527068730&sign=fd8cc3348652b9cbf2714689ab7ee9105da67cf4

继续修改上例中的userclient.php文件,再分别使用get()方法请求3次userapi.php接口,第一次没有添加“sign”参数,第二次使用错误的“sign”参数,第三次使用全部正确的参数。并通过上面的算法生成“sign”参数。修改后代码片段如下所示:

同样地,修改userapi.php接口文件,判断在请求接口时,请求的URL是否带有“sign”参数,和客户端使用相同的算法计算签名,并和URL中接收到的客户端“sign”参数进行匹配,如果相同则返回数据,如果不同则可能被篡改,返回错误消息。修改后代码片段如下所示:

运行的结果如图23-9所示:

图23-9 测试请求API的URL参数带有sign的结果

通过签名参数,能大大提高接口的安全性,其他人不能随意地请求接口。虽然有人也可以抓取接口地址,但是也只能获取这一条数据,不能请求别的数据。例如,有人抓取了上例中的这个接口地址,它只能获取ID为1的文章。并且5分钟的时间内,它无法通过修改参数来获取ID为100的文章,因为一旦参数变化,“sign”参数校验就会失败。支付宝接口就是这样做的,避免交易金额随便被更改。

3. 引入token

虽然通过添加“时间戳”和“签名”参数,接口相对比较安全了,但是还是有隐患,如果别人知道了加密规则(当然规则可以变化,如倒序排序,或双层sha1加密等),采用相同的规则加密参数得到“sign”,就能接着获取其他的数据了。所以,需要再引入另一个元素“token”,它是一个约定值,相当于“暗号”,其实就是只有客户端和服务器端知道的一个随机字符串。当然这个“token”字符串在客户端用户那里是不可见的,如果客户端是App,代码是编译过的,客户端使用PHP程序,在服务器上不会传给用户。引入“token”只需要将这个随机的字符串加入sign 的计算中,就能再次提高接口的安全性。 继续修改上例中的userclient.php文件,引入“token”进入签名运算。修改后代码片段如下所示:

继续修改上例中的userapi.php文件,同样引入相同内容的“token”进入签名运算中。修改后代码片段如下所示:

再次运行后,和上例运行得到的结果相同。到此为止,我们的接口已经变得比较的安全了,其他人想要请求我们的接口,就必须知道我们的签名加密规则和随机的“token”字符串,这个可能性就太低了。

delphi 调用php接口_《细说PHP》第四版 样章 第23章 自定义PHP接口规范 5相关推荐

  1. delphi 调用php接口_贝壳找房小程序从PHP到Golang的跃迁之路

    1. 前言 1.1 PHP是最好的语言 PHP确实有非常强大的优势.对于中小型Web服务,业务具有高度不确定性,产品迭代速度是第一目标,非常适合使用PHP作为创业启动语言. 1.2 使用PHP遇到的问 ...

  2. delphi 调用php接口_新浪图床 API 接口调用与请求方法详细教程

    新浪微博图床API在网上已经很多且大都封装成了API供别人调用,这里分享其核心代码.支持前台跨域请求,以POST方式提交图片即可.新浪图床可以将你的图片远程上传到新浪服务器,你可以选择调用本站的接口, ...

  3. delphi 调用php接口_爱站权重查询 API 接口请求调用

    爱站权重查询 API 接口在网上已经很多且大都封装成了 API 供别人调用.支持前台跨域请求,以GET/POST方式提交即可.爱站权重查询 API 接口可以查询百度权重.搜狗等级.360权重.神马权重 ...

  4. java调用easyxml接口_【技术教程】如何通过Java程序调用RTSP拉流协议视频平台EasyNVR程序接口?...

    原标题:[技术教程]如何通过Java程序调用RTSP拉流协议视频平台EasyNVR程序接口? RTSP协议视频平台EasyNVR经过多年的积累,已经是一套成熟且完善的视频平台了,用户可以通过网页直接访 ...

  5. postman调用webservice接口_【分享】关于接口对前后端和测试的意义

    1.什么是接口? 接口测试主要用于外部系统与系统之间以及内部各个子系统之间的交互点,定义特定的交互点,然后通过这些交互点来,通过一些特殊的规则也就是协议,来进行数据之间的交互. 2.接口都有哪些类型? ...

  6. postman调用webservice接口_接口对前后端和测试的意义

    1.什么是接口? 接口测试主要用于外部系统与系统之间以及内部各个子系统之间的交互点,定义特定的交互点,然后通过这些交互点来,通过一些特殊的规则也就是协议,来进行数据之间的交互. 2.接口都有哪些类型? ...

  7. webstorm前端调用后端接口_软件测试面试题:怎么去判断一个bug是前端问题还是后端问题...

    大家好,在软件测试面试过程中,经常有面试官问到这个问题,那我们应该如何回答才好呢?少废话,直接看答案: 答案: 在页面上发现bug之后,要想判断这个问题属于后端还是前端,我就需要来判断这个页面背后调用 ...

  8. c调用python接口_通过Python自带C/C++接口实现python与c/c++相互调用

    python的底层是c/c++,因此两种语言都有相互的接口,在以前已经写过一篇c++调用python接口让opencv中的cv::Mat类型在两种语言中相互传递,ubuntu下C++与Python混编 ...

  9. java异步调用微信接口_微信支付V3 SDK(Java版,支持同步异步调用)

    我们在开发微信支付时,发现微信官方已经对SDK做了升级,V3版本的SDK从设计上符合RESTful规范. 我们再在开源库中寻找是否有现成de开箱即用.并且支持响应式编程的SDK版本.经过一凡寻找,令我 ...

最新文章

  1. Spring Cloud(二): 注册中心Eureka的使用
  2. iOS 本地时间与GMT时间相互转换
  3. JVM之Java类加载器
  4. 阿里云发布 Spring Boot 新脚手架,真香
  5. lnmp之php5.6.29安装
  6. 实战系列-IDEA中Spring MVC实现接口功能
  7. 安卓手机软件开发_奇怪!苹果手机运存小,流畅度反而胜于安卓,今天终于明白了...
  8. Python科学计算扩展库numpy中的广播运算
  9. linux内核之进程管理详解
  10. js函数内部定义函数的理解
  11. linux显示器复制模式,屏幕扩展模式、复制模式与合并模式
  12. android 自定义indicator,Android自定义Indicator
  13. Manjaro Linux 双显卡安装步骤及独立显卡运行游戏(Nvidia GeForce GTX 980m)
  14. 我的世界java多人不刷溺尸_我的世界:不同版本的三叉戟掉落率不一样?刷了一两百溺尸也没有!...
  15. 技巧分享-如何给电脑“重装”系统(win10)
  16. 2019CCPC女生专场赛_K - Tetris_打表/模拟_暴力之王
  17. PHP登陆页面完整代码
  18. AP AUTOSAR 6——Execution Management
  19. 解决python爬虫出现的521问题
  20. 三国志战略版:奸雄骑,不要奸雄

热门文章

  1. AngularJS日期格式化
  2. XML万能数据库设计
  3. jQuery 学习笔记之十二 (选项卡)
  4. 安装非认证的chrome插件和设置文件夹的权限
  5. ERROR in ./src/css/1.scss 1:2
  6. [ES6] 细化ES6之 -- 前端模块化
  7. JavaScript学习笔记(二)--流程控制语句
  8. 计算机视觉中的牛人贡献及其主页
  9. 动手学深度学习(PyTorch实现)(三)--过拟合与欠拟合
  10. #ifndef#define与namespace杂谈