1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
// +---------------------------------------------------------------------- |
4
|
|
|
// | ThinkLibrary 6.0 for ThinkPhP 6.0 |
5
|
|
|
// +---------------------------------------------------------------------- |
6
|
|
|
// | 版权所有 2017~2020 [ https://www.dtapp.net ] |
7
|
|
|
// +---------------------------------------------------------------------- |
8
|
|
|
// | 官方网站: https://gitee.com/liguangchun/ThinkLibrary |
9
|
|
|
// +---------------------------------------------------------------------- |
10
|
|
|
// | 开源协议 ( https://mit-license.org ) |
11
|
|
|
// +---------------------------------------------------------------------- |
12
|
|
|
// | gitee 仓库地址 :https://gitee.com/liguangchun/ThinkLibrary |
13
|
|
|
// | github 仓库地址 :https://github.com/GC0202/ThinkLibrary |
14
|
|
|
// | gitlab 仓库地址 :https://gitlab.com/liguangchun/thinklibrary |
15
|
|
|
// | weixin 仓库地址 :https://git.weixin.qq.com/liguangchun/ThinkLibrary |
16
|
|
|
// | huaweicloud 仓库地址 :https://codehub-cn-south-1.devcloud.huaweicloud.com/composer00001/ThinkLibrary.git |
17
|
|
|
// | Packagist 地址 :https://packagist.org/packages/liguangchun/think-library |
18
|
|
|
// +---------------------------------------------------------------------- |
19
|
|
|
|
20
|
|
|
namespace DtApp\ThinkLibrary; |
21
|
|
|
|
22
|
|
|
use DtApp\ThinkLibrary\helper\ValidateHelper; |
23
|
|
|
use stdClass; |
24
|
|
|
use think\App; |
25
|
|
|
use think\exception\HttpResponseException; |
26
|
|
|
use think\Request; |
27
|
|
|
|
28
|
|
|
/** |
29
|
|
|
* 标准Api控制器基类 |
30
|
|
|
* Class ApiController |
31
|
|
|
* @package DtApp\ThinkLibrary |
32
|
|
|
*/ |
33
|
|
|
abstract class ApiController extends stdClass |
34
|
|
|
{ |
35
|
|
|
/** |
36
|
|
|
* 应用容器 |
37
|
|
|
* @var App |
38
|
|
|
*/ |
39
|
|
|
public $app; |
40
|
|
|
|
41
|
|
|
/** |
42
|
|
|
* 请求对象 |
43
|
|
|
* @var Request |
44
|
|
|
*/ |
45
|
|
|
public $request; |
46
|
|
|
|
47
|
|
|
/** |
48
|
|
|
* 解密后数据 |
49
|
|
|
* @var |
50
|
|
|
*/ |
51
|
|
|
private $aes_decrypt_data; |
52
|
|
|
|
53
|
|
|
/** |
54
|
|
|
* 加密相关的东西 |
55
|
|
|
* @var string |
56
|
|
|
*/ |
57
|
|
|
private $aes_md5, $aes_md5_iv = ''; |
58
|
|
|
|
59
|
|
|
/** |
60
|
|
|
* ApiController constructor. |
61
|
|
|
* @param App $app |
62
|
|
|
*/ |
63
|
|
|
public function __construct(App $app) |
64
|
|
|
{ |
65
|
|
|
$this->app = $app; |
66
|
|
|
$this->request = $app->request; |
67
|
|
|
$this->app->bind('DtApp\ThinkLibrary\ApiController', $this); |
68
|
|
|
if (in_array($this->request->action(), get_class_methods(__CLASS__))) { |
69
|
|
|
$this->error('Access without permission.'); |
70
|
|
|
} |
71
|
|
|
$this->initialize(); |
72
|
|
|
} |
73
|
|
|
|
74
|
|
|
/** |
75
|
|
|
* 控制器初始化 |
76
|
|
|
*/ |
77
|
|
|
protected function initialize() |
78
|
|
|
{ |
79
|
|
|
} |
80
|
|
|
|
81
|
|
|
/** |
82
|
|
|
* 返回失败的操作 |
83
|
|
|
* @param mixed $msg 消息内容 |
84
|
|
|
* @param mixed $data 返回数据 |
85
|
|
|
* @param integer $code 返回代码 |
86
|
|
|
*/ |
87
|
|
|
public function error($msg = 'error', $code = 1, $data = []): void |
88
|
|
|
{ |
89
|
|
|
throw new HttpResponseException(json([ |
90
|
|
|
'code' => $code, |
91
|
|
|
'msg' => $msg, |
92
|
|
|
'timestamp' => time(), |
93
|
|
|
'data' => $data, |
94
|
|
|
])); |
95
|
|
|
} |
96
|
|
|
|
97
|
|
|
/** |
98
|
|
|
* 返回成功的操作 |
99
|
|
|
* @param mixed $msg 消息内容 |
100
|
|
|
* @param mixed $data 返回数据 |
101
|
|
|
* @param integer $code 返回代码 |
102
|
|
|
*/ |
103
|
|
|
public function success($data = [], $msg = 'success', $code = 0): void |
104
|
|
|
{ |
105
|
|
|
throw new HttpResponseException(json([ |
106
|
|
|
'code' => $code, |
107
|
|
|
'msg' => $msg, |
108
|
|
|
'timestamp' => time(), |
109
|
|
|
'data' => $data, |
110
|
|
|
])); |
111
|
|
|
} |
112
|
|
|
|
113
|
|
|
/** |
114
|
|
|
* key |
115
|
|
|
* @param string $name 参数名 |
116
|
|
|
* @return $this |
117
|
|
|
*/ |
118
|
|
|
public function setAesMd5($name = 'sniff_h5'): self |
119
|
|
|
{ |
120
|
|
|
$value = config("dtapp.md5.{$name}"); |
121
|
|
|
$this->aes_md5 = $value; |
|
|
|
|
122
|
|
|
return $this; |
123
|
|
|
} |
124
|
|
|
|
125
|
|
|
/** |
126
|
|
|
* iv |
127
|
|
|
* @return $this |
128
|
|
|
*/ |
129
|
|
|
private function setAesMd5Iv(): self |
130
|
|
|
{ |
131
|
|
|
$value = config("dtapp.md5.bcw"); |
132
|
|
|
$this->aes_md5_iv = $value; |
|
|
|
|
133
|
|
|
return $this; |
134
|
|
|
} |
135
|
|
|
|
136
|
|
|
/** |
137
|
|
|
* 返回成功的操作 |
138
|
|
|
* @param mixed $data 返回数据 |
139
|
|
|
* @param mixed $msg 消息内容 |
140
|
|
|
* @param integer $code 返回代码 |
141
|
|
|
*/ |
142
|
|
|
public function aesSuccess($data = [], $msg = 'success', $code = 0) |
143
|
|
|
{ |
144
|
|
|
$timestamp = time(); |
145
|
|
|
throw new HttpResponseException(json([ |
146
|
|
|
'code' => $code, |
147
|
|
|
'msg' => $msg, |
148
|
|
|
'timestamp' => $timestamp, |
149
|
|
|
'data' => [ |
150
|
|
|
'aes' => $this->encrypt($data, $timestamp) |
151
|
|
|
], |
152
|
|
|
])); |
153
|
|
|
} |
154
|
|
|
|
155
|
|
|
/** |
156
|
|
|
* URL重定向 |
157
|
|
|
* @param string $url 跳转链接 |
158
|
|
|
* @param integer $code 跳转代码 |
159
|
|
|
*/ |
160
|
|
|
public function redirect($url, $code = 301): void |
161
|
|
|
{ |
162
|
|
|
throw new HttpResponseException(redirect($url, $code)); |
163
|
|
|
} |
164
|
|
|
|
165
|
|
|
/** |
166
|
|
|
* @param array $rules |
167
|
|
|
* @param string $type |
168
|
|
|
* @return mixed |
169
|
|
|
*/ |
170
|
|
|
protected function _vali(array $rules, $type = '') |
171
|
|
|
{ |
172
|
|
|
return ValidateHelper::instance() |
173
|
|
|
->init($rules, $type); |
|
|
|
|
174
|
|
|
} |
175
|
|
|
|
176
|
|
|
/** |
177
|
|
|
* 获取解密后的数据 |
178
|
|
|
* @param string $name |
179
|
|
|
* @param null $default |
|
|
|
|
180
|
|
|
* @return mixed |
181
|
|
|
*/ |
182
|
|
|
public function getAesDecryptData(string $name = '', $default = null) |
183
|
|
|
{ |
184
|
|
|
if (empty($name)) { |
185
|
|
|
return $this->aes_decrypt_data; |
186
|
|
|
} |
187
|
|
|
|
188
|
|
|
return $this->aes_decrypt_data[$name] ?? $default; |
189
|
|
|
} |
190
|
|
|
|
191
|
|
|
/** |
192
|
|
|
* 验证接口签名 |
193
|
|
|
*/ |
194
|
|
|
public function _judgeSign() |
195
|
|
|
{ |
196
|
|
|
// 加密的数据参数 |
197
|
|
|
$aes = $this->request->post('aes', ''); |
198
|
|
|
if (empty($aes)) { |
199
|
|
|
$this->error('数据未签名!', 104); |
200
|
|
|
} |
201
|
|
|
// 获取时间数据 |
202
|
|
|
$timestamp = $this->request->get('timestamp', 0); |
203
|
|
|
// 判断是否有时间 |
204
|
|
|
if (empty($timestamp)) { |
205
|
|
|
$this->error('数据异常!', 105); |
206
|
|
|
} |
207
|
|
|
// 解密 |
208
|
|
|
$aes_decode = $this->decrypt($aes, $timestamp); |
|
|
|
|
209
|
|
|
if (empty($aes_decode)) { |
210
|
|
|
$this->error('解密失败', 106); |
211
|
|
|
} |
212
|
|
|
$data = json_decode($aes_decode, true); |
213
|
|
|
// 判断是不是小于服务器时间 |
214
|
|
|
$before = strtotime('-2minute'); |
215
|
|
|
$rear = strtotime('+2minute'); |
216
|
|
|
if ($timestamp <= $rear && $timestamp >= $before) { |
217
|
|
|
$this->aes_decrypt_data = $data; |
218
|
|
|
} else { |
219
|
|
|
$this->error('已超时,请重新尝试!'); |
220
|
|
|
} |
221
|
|
|
} |
222
|
|
|
|
223
|
|
|
/** |
224
|
|
|
* 加密 |
225
|
|
|
* @param $data |
226
|
|
|
* @param int $timestamp |
227
|
|
|
* @return bool|string |
228
|
|
|
*/ |
229
|
|
|
private function encrypt($data, int $timestamp) |
230
|
|
|
{ |
231
|
|
|
if (empty($this->aes_md5)) { |
232
|
|
|
$this->setAesMd5(); |
233
|
|
|
} |
234
|
|
|
if (empty($this->aes_md5_iv)) { |
235
|
|
|
$this->setAesMd5Iv(); |
236
|
|
|
} |
237
|
|
|
if (!empty(is_array($data))) { |
238
|
|
|
$data = json_encode($data); |
239
|
|
|
} |
240
|
|
|
return urlencode(base64_encode(openssl_encrypt($data, 'AES-128-CBC', $this->aes_md5, 1, $this->aes_md5_iv . $timestamp))); |
241
|
|
|
} |
242
|
|
|
|
243
|
|
|
/** |
244
|
|
|
* 解密 |
245
|
|
|
* @param string $data |
246
|
|
|
* @param int $timestamp |
247
|
|
|
* @return bool|false|string |
248
|
|
|
*/ |
249
|
|
|
private function decrypt(string $data, int $timestamp) |
250
|
|
|
{ |
251
|
|
|
if (empty($this->aes_md5)) { |
252
|
|
|
$this->setAesMd5(); |
253
|
|
|
} |
254
|
|
|
if (empty($this->aes_md5_iv)) { |
255
|
|
|
$this->setAesMd5Iv(); |
256
|
|
|
} |
257
|
|
|
return openssl_decrypt(base64_decode(urldecode($data)), "AES-128-CBC", $this->aes_md5, true, $this->aes_md5_iv . $timestamp); |
|
|
|
|
258
|
|
|
} |
259
|
|
|
} |
260
|
|
|
|
Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.
For example, imagine you have a variable
$accountId
that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to theid
property of an instance of theAccount
class. This class holds a proper account, so the id value must no longer be false.Either this assignment is in error or a type check should be added for that assignment.