就安全来说,所有客户端和服务器端的通信内容应该都要通过加密通道(HTTPS)传输,明文的HTTP通道将会是man-in-the- middle及其各种变种攻击的温床。所谓man-in-the-middle攻击简单讲就是指恶意的黑客可以在客户端和服务器端的明文通信通道上做手 脚,黑客可以监听通信内容,偷取机密信息,甚至可以篡改通信内容,而通过加密后的通信内容理论上是无法被破译的。

URL签名生成规则

API的有效访问URL包括以下三个部分:
1. 资源访问路径,如/v1/deal/find_deals;
2. 请求参数:即API对应所需的参数名和参数值param=value,多个请求参数间用&连接如deal_id=1-85462&appid=00000;
3. 签名串,由签名算法生成

签名算法如下:

1. 对所有请求参数进行字典升序排列;
2. 将以上排序后的参数表进行字符串连接,如key1value1key2value2key3value3...keyNvalueN;
3. app secret作为后缀,对该字符串进行SHA-1计算,并转换成16进制编码;
4. 转换为全大写形式后即获得签名串

注意:请保证HTTP请求数据编码务必为UTF-8格式,URL也务必为UTF-8编码格式。

举个实例:

PHP服务端先要给开发者(APP)分配一个appid与appsecret (正常情况下,开发者要到服务提供商的官网申请),作为客户端,需要保留好官方颁发的appid & appsecret

appid会在请求中作为一个应用标识参与接口请求的参数传递,appsecret 将作为唯一不需要参数传递,但是它将作为验证当前请求的关键参数,只有应用开发者和颁发的服务端才知道。由于签名是依靠同样的算法加密实现,因此,应用端和服务端可以计算出相同的签名值,签名实际意义在于服务端对客户端的访问身份认证。在某种意义上签名机制有点类似用公钥方法签名,用每个应用对应的私钥值来解密,只是这种解密过程实质就是核对签名参数值的过程。
假设分配:

$appid=5288971;
$appsecret= 'r5e2t85tyu142u665698fzu';

移动客户端,需要请求服务列表(以下代码可以为java或sf等移动端编写)
请求地址: http://web.com/server/list

参数:

$array=[
'appid'=>5288971,
'menu'=>'客户服务列表',
'lat'=>21.223,
'lng'=>131.334
];

对应签名算法

// 1. 对加密数组进行字典排序 防止因为参数顺序不一致而导致下面拼接加密不同
ksort($array);
// 2. 将Key和Value拼接
$str = "";
foreach ($array as $k => $v) {
$str.= $k.$v;
} //3. 通过sha1加密并转化为大写
//4. 大写获得签名
$restr=$str.$appsecret;
$sign = strtoupper(sha1($restr)); 

将生产的sign签名一起写入array中,通过约定好的method方式发送参数到请求接口

$array['sign']=$sign;

打印$array

Array
(
[appid] => 5288971
[menu] => 客户服务列表
[lat] => 21.223
[lng] => 131.334
[sign] => C096D7811E944386CE880597BA334A5AB640B088
)

客户端将数据封装xml或Json发送到服务端,服务端先解析

{"appid":5288971,"menu":"\u5ba2\u6237\u670d\u52a1\u5217\u8868","lat":21.223,"lng":131.334,"sign":"C096D7811E944386CE880597BA334A5AB640B088"}
$serverArray= json_decode($json,TRUE);

服务端查询appid对应的密钥

$model=Model::find()->where("appid=:appid")->params([":appid"=>$serverArray['appid']])->one();
if($model){
$serverSecret=$model->appsecret;
}

按照相同的字典排序与算法生成服务端的$sign ,判断$sign 是否相同。

$clientSign=$serverArray['sign'];
unset($serverArray['sign']);
#生成服务端str
$serverstr = "";
foreach ($serverArray as $k => $v) {
$serverstr.= $k.$v;
}
$reserverstr=$serverstr.$serverSecret;
$reserverSign = strtoupper(sha1($reserverstr)); if($clientSign!=$reserverSign){
die('非法请求');
}else{
// your code continue;
}

在仅适用短信登录做手机端app时,可以设置secret的过期时间,短信登录后,保存appid(userid)与密钥secret,每当用户打开APP时,先联网请求登录是否过期,过期重新短信登录获取新的secret。

附加:

有时,我们使用hash_hmac进行加密(我们项目中使用……)

/*
* 生成签名,$args为请求参数,$key为私钥
*/
function makeSignature($args, $key)
{
if(isset($args['sign'])) {
$oldSign = $args['sign'];
unset($args['sign']);
} else {
$oldSign = '';
} ksort($args);
$requestString = '';
foreach($args as $k => $v) {
$requestString .= $k . '=' . urlencode($v);
}
$newSign = hash_hmac("md5",strtolower($requestString) , $key);
return $newSign;
}

javascript 进行加密签名

微信小程序开发的时候,为了数据的安全,也可以用js对数据签名,发送服务器进行效验认证.

先引入md5.js

<script src="https://cdn.bootcss.com/blueimp-md5/2.10.0/js/md5.js"></script>
 var postData =<?php echo json_encode($data); ?>;
var token ='<?php echo token; ?>';
/**
* json 排序
* 先排序再toLower,所以Did 在appid 之前
*/
function jsonSort(jsonObj) {
let arr = [];
for (var key in jsonObj) {
arr.push(key)
}
arr.sort();
let str = '';
for (var i in arr) {
str += arr[i].toLowerCase() + "=" + jsonObj[arr[i]].toLowerCase();
}
return str
} strData = jsonSort(postData);
var sign = md5(strData, token);
postData['sign'] = sign;
console.log(postData);

JS-PHP 加密解密demo: https://files.cnblogs.com/files/dcb3688/php.javascript.encrypMD5.php.7z

PHP 开发API接口签名验证的更多相关文章

  1. 转载-常用API接口签名验证参考

    原文地址: http://www.cnblogs.com/hnsongbiao/p/5478645.html 写的很好,就做个笔记了.感谢作者! 项目中常用的API接口签名验证方法: 1. 给app分 ...

  2. 智表ZCELL产品V1.4.0开发API接口文档 与 产品功能清单

    为了方便大家使用ZCELL,应网友要求,整理编写了相关文档,现与产品一起同步发布,供大家下载使用,使用过程中如有疑问,请与我QQ联系. 智表(ZCELL)V1.4.0版本  功能清单文档下载地址: 功 ...

  3. 常用API接口签名验证参考

    项目中常用的API接口签名验证方法: 1. 给app分配对应的key.secret2. Sign签名,调用API 时需要对请求参数进行签名验证,签名方式如下: a. 按照请求参数名称将所有请求参数按照 ...

  4. 开放api接口签名验证

    不要急,源代码分享在最底部,先问大家一个问题,你在写开放的API接口时是如何保证数据的安全性的?先来看看有哪些安全性问题在开放的api接口中,我们通过http Post或者Get方式请求服务器的时候, ...

  5. api接口签名验证(MD5)

    不要急,源代码分享在最底部,先问大家一个问题,你在写开放的API接口时是如何保证数据的安全性的?先来看看有哪些安全性问题在开放的api接口中,我们通过http Post或者Get方式请求服务器的时候, ...

  6. php开发api接口

    做过 API 的人应该了解,其实开发 API 比开发 WEB 更简洁,但可能逻辑更复杂,因为 API 其实就是数据输出,不用呈现页面,所以也就不存在 MVC(API 只有 M 和 C),那么我们来探讨 ...

  7. 【转】开放api接口签名验证

    不要急,源代码分享在最底部,先问大家一个问题,你在写开放的API接口时是如何保证数据的安全性的?先来看看有哪些安全性问题在开放的api接口中,我们通过http Post或者Get方式请求服务器的时候, ...

  8. 简单天气应用开发——API接口

    寒假回家无事,想到自学iOS开发已有一段时间,还没做过真正自己的应用,就起了做一个天气预报App的念头. 想到就做.天气预报第一步自然是找到好用的API接口来获取天气信息.在百度上搜索了一圈,找到的都 ...

  9. PHP开发api接口安全验证

    php的api接口 在实际工作中,使用PHP写api接口是经常做的,PHP写好接口后,前台就可以通过链接获取接口提供的数据,而返回的数据一般分为两种情况,xml和json,在这个过程中,服务器并不知道 ...

随机推荐

  1. hibernate优化笔记(随时更新)

    一:优化配置 1.关联映射的配置:对照之前的博客,如:inverse属性的设置(减少对同一对象的多条update语句):在one端设置为true,只会执行一次update语句 2.级联cascade属 ...

  2. PHP的final关键字、static关键字、const关键字

    在PHP5中新增加了final关键字,它可以加载类或类中方法前.但不能使用final标识成员属性,虽然final有常量的意思,但在php中定义常量是使用define()函数来完成的. final关键字 ...

  3. web主题公园版权信息破解:script.js加密文件

    很多人会使用web主题公园网站的免费worldpress主题,但它的主题又都被加了版权信息,故意让人找不到版权信息的修改位置. 你如果去footer.php里面删除版权信息(技术支持:web主题公园) ...

  4. 用ffmpeg合并音频文件

    1 问题描述 打电话的对话,被拆分成了两个PCM文件.其中主叫的录音文件A.pcm,被叫的录音为B.pcm. 问题是怎么合成一个混音的对话文件AB.wav. 2 WAV文件的录音格式 常见的声音文件主 ...

  5. Kinect开发资源汇总

    Kinect开发资源汇总   转自: http://www.sigvc.org/bbs/forum.php?mod=viewthread&tid=254&highlight=kinec ...

  6. 安卓中AIDL的使用方法快速入门

    1.AIDL是什么? AIDL全称是Android Interface Definition Language,即安卓接口定义语言. 2.AIDL是用来做什么的?(为什么要有AIDL) AIDL是用来 ...

  7. 几个常用的Linux命令

    最近在学习Linux,记录了几个命令如下: 首先认识:关机命令,我喜欢用的是:shutdown -h now ,当然还有init 0等命令(用自己习惯的);重启命令:reboot;注销命令:logou ...

  8. 页面滚动到底部自动 Ajax 获取文章

    页面滚动到底部自动 Ajax 获取文章  代码如下 复制代码 var _timer = {};function delay_till_last(id, fn, wait) {    if (_time ...

  9. MySQL 优化MySQL Server

    一.使用show variables 和show status 命令查看MySQL的服务器静态参数值和动态运行状态信息. 二.可以使用 mysqld --verbose --help|more 查看某 ...

  10. linux Mint mysql 安装

    sudo apt-get install mysql-server 之后按照提示,输入root的密码,再次输入密码,就好了. mysql -uroot -p**** //连接数据库 show data ...