ApiSig.class.php
3.43 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
<?php
/**
* ApiSig.class.php
* 全局 Api 签名验证算法
*
* @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL
* @copyright Copyright (c) 2014 - ? VcySDK (http://www.vchangyi.com/)
* @author zhuxun37
* @version 1.0.0
*/
namespace VcySDK;
class ApiSig
{
/**
* 秘钥
*
* @var $secret
*/
protected $secret = '';
/**
* 签名有效时间(单位: 秒)
*
* @var $expire
*/
protected $expire = 600;
/**
* 实例化
*
* @param string $secret 秘钥
* @param int $expire 有效时间
*
* @return ApiSig
*/
public static function &instance($secret = '', $expire = 600)
{
static $instance;
// 有效时间
$expire = empty($expire) ? Config::instance()->apiSigExpire : $expire;
// 秘钥
$secret = empty($secret) ? Config::instance()->apiSecret : $secret;
// 根据秘钥初始化
$md5 = md5($secret);
if (empty($instance[$md5])) {
$instance[$md5] = new self($secret, $expire);
}
return $instance[$md5];
}
public function __construct($secret, $expire)
{
$this->secret = $secret;
$this->expire = $expire;
}
/**
* 生成签名
*
* @param mixed $obj 签名数据
* @param array $params 参数
*
* @return string
*/
public function getSig($obj, $params = array())
{
// 签名步骤一:按字典序排序参数
$obj['timestamp'] = ! empty($params['timestamp']) ? $params['timestamp'] : NOW_TIME;
$String = $this->formatBizQueryParaMap($obj);
// 签名步骤二:在string后加入KEY
$String = $String . $this->secret;
// 签名步骤三: 加密字符串,并大写
$String = strtoupper(sha1($String));
return $String;
}
/**
* 格式化参数
*
* @param $paraMap
* @param $urlencode
*
* @return string
*/
protected function formatBizQueryParaMap($paraMap, $urlencode = false)
{
$buff = "";
ksort($paraMap);
foreach ($paraMap as $v) {
if ($urlencode) {
$v = urlencode($v);
}
$buff .= is_array($v) ? $this->formatBizQueryParaMap($v) : $v;
}
return $buff;
}
/**
* 获取签名等参数并验证
*
* @param array $data 要签名的数组
* @param string $method 获取数据的方式 GET | POST
*
* @return bool
* @throws \VcySDK\Exception
*/
public function getParamAndCheck($data, $method = 'POST')
{
if (empty($data)) {
// 获取数据
$data = $method == 'POST' ? I('post.') : I('get.');
}
// 验证签名
if ($this->check($data)) {
return $data;
};
return false;
}
/**
* 检查默认 sig
*
* @param $param
*
* @return bool
* @throws \VcySDK\Exception
*/
public function check($param)
{
// 检查时间
if ($param['timestamp'] + $this->expire < NOW_TIME) {
throw new Exception(Error::APISIG_REQUEST_EXPIRED);
return false;
}
// 如果签名不相等
if ($param['sign'] != $this->getSig($param)) {
throw new Exception(Error::APISIG_ERROR);
return false;
}
return true;
}
}