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 | // | Packagist 地址 :https://packagist.org/packages/liguangchun/think-library |
||||||
15 | // +---------------------------------------------------------------------- |
||||||
16 | |||||||
17 | namespace DtApp\ThinkLibrary; |
||||||
18 | |||||||
19 | use DtApp\ThinkLibrary\helper\ValidateHelper; |
||||||
20 | use stdClass; |
||||||
21 | use think\App; |
||||||
22 | use think\exception\HttpResponseException; |
||||||
23 | use think\Request; |
||||||
24 | |||||||
25 | /** |
||||||
26 | * 标准Api控制器基类 |
||||||
27 | * Class ApiController |
||||||
28 | * @package DtApp\ThinkLibrary |
||||||
29 | */ |
||||||
30 | abstract class ApiController extends stdClass |
||||||
31 | { |
||||||
32 | /** |
||||||
33 | * 应用容器 |
||||||
34 | * @var App |
||||||
35 | */ |
||||||
36 | public $app; |
||||||
37 | |||||||
38 | /** |
||||||
39 | * 请求对象 |
||||||
40 | * @var Request |
||||||
41 | */ |
||||||
42 | public $request; |
||||||
43 | |||||||
44 | /** |
||||||
45 | * 解密后数据 |
||||||
46 | * @var |
||||||
47 | */ |
||||||
48 | private $aes_decrypt_data; |
||||||
49 | |||||||
50 | /** |
||||||
51 | * 加密相关的东西 |
||||||
52 | * @var string |
||||||
53 | */ |
||||||
54 | private $aes_md5, $aes_md5_iv = ''; |
||||||
55 | |||||||
56 | /** |
||||||
57 | * ApiController constructor. |
||||||
58 | * @param App $app |
||||||
59 | */ |
||||||
60 | public function __construct(App $app) |
||||||
61 | { |
||||||
62 | $this->app = $app; |
||||||
63 | $this->request = $app->request; |
||||||
64 | $this->app->bind('DtApp\ThinkLibrary\ApiController', $this); |
||||||
65 | if (in_array($this->request->action(), get_class_methods(__CLASS__))) { |
||||||
66 | $this->error('Access without permission.'); |
||||||
67 | } |
||||||
68 | $this->initialize(); |
||||||
69 | } |
||||||
70 | |||||||
71 | /** |
||||||
72 | * 控制器初始化 |
||||||
73 | */ |
||||||
74 | protected function initialize() |
||||||
75 | { |
||||||
76 | } |
||||||
77 | |||||||
78 | /** |
||||||
79 | * 返回失败的操作 |
||||||
80 | * @param mixed $msg 消息内容 |
||||||
81 | * @param mixed $data 返回数据 |
||||||
82 | * @param integer $code 返回代码 |
||||||
83 | */ |
||||||
84 | public function error($msg = 'error', $code = 1, $data = []): void |
||||||
85 | { |
||||||
86 | throw new HttpResponseException(json([ |
||||||
87 | 'code' => $code, |
||||||
88 | 'msg' => $msg, |
||||||
89 | 'timestamp' => time(), |
||||||
90 | 'data' => $data, |
||||||
91 | ])); |
||||||
92 | } |
||||||
93 | |||||||
94 | /** |
||||||
95 | * 返回成功的操作 |
||||||
96 | * @param mixed $msg 消息内容 |
||||||
97 | * @param mixed $data 返回数据 |
||||||
98 | * @param integer $code 返回代码 |
||||||
99 | */ |
||||||
100 | public function success($data = [], $msg = 'success', $code = 0): void |
||||||
101 | { |
||||||
102 | throw new HttpResponseException(json([ |
||||||
103 | 'code' => $code, |
||||||
104 | 'msg' => $msg, |
||||||
105 | 'timestamp' => time(), |
||||||
106 | 'data' => $data, |
||||||
107 | ])); |
||||||
108 | } |
||||||
109 | |||||||
110 | /** |
||||||
111 | * key |
||||||
112 | * @param string $name 参数名 |
||||||
113 | * @return $this |
||||||
114 | */ |
||||||
115 | public function setAesMd5($name = 'sniff_h5'): self |
||||||
116 | { |
||||||
117 | $value = config("dtapp.md5.{$name}"); |
||||||
118 | $this->aes_md5 = $value; |
||||||
0 ignored issues
–
show
|
|||||||
119 | return $this; |
||||||
120 | } |
||||||
121 | |||||||
122 | /** |
||||||
123 | * iv |
||||||
124 | * @return $this |
||||||
125 | */ |
||||||
126 | private function setAesMd5Iv(): self |
||||||
127 | { |
||||||
128 | $value = config("dtapp.md5.bcw"); |
||||||
129 | $this->aes_md5_iv = $value; |
||||||
0 ignored issues
–
show
It seems like
$value can also be of type boolean . However, the property $aes_md5_iv is declared as type string . Maybe add an additional type check?
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 Either this assignment is in error or a type check should be added for that assignment. class Id
{
public $id;
public function __construct($id)
{
$this->id = $id;
}
}
class Account
{
/** @var Id $id */
public $id;
}
$account_id = false;
if (starsAreRight()) {
$account_id = new Id(42);
}
$account = new Account();
if ($account instanceof Id)
{
$account->id = $account_id;
}
![]() |
|||||||
130 | return $this; |
||||||
131 | } |
||||||
132 | |||||||
133 | /** |
||||||
134 | * 返回成功的操作 |
||||||
135 | * @param mixed $data 返回数据 |
||||||
136 | * @param mixed $msg 消息内容 |
||||||
137 | * @param integer $code 返回代码 |
||||||
138 | */ |
||||||
139 | public function aesSuccess($data = [], $msg = 'success', $code = 0) |
||||||
140 | { |
||||||
141 | $timestamp = time(); |
||||||
142 | throw new HttpResponseException(json([ |
||||||
143 | 'code' => $code, |
||||||
144 | 'msg' => $msg, |
||||||
145 | 'timestamp' => $timestamp, |
||||||
146 | 'data' => [ |
||||||
147 | 'aes' => $this->encrypt($data, $timestamp) |
||||||
148 | ], |
||||||
149 | ])); |
||||||
150 | } |
||||||
151 | |||||||
152 | /** |
||||||
153 | * URL重定向 |
||||||
154 | * @param string $url 跳转链接 |
||||||
155 | * @param integer $code 跳转代码 |
||||||
156 | */ |
||||||
157 | public function redirect($url, $code = 301): void |
||||||
158 | { |
||||||
159 | throw new HttpResponseException(redirect($url, $code)); |
||||||
160 | } |
||||||
161 | |||||||
162 | /** |
||||||
163 | * @param array $rules |
||||||
164 | * @param string $type |
||||||
165 | * @return mixed |
||||||
166 | */ |
||||||
167 | protected function _vali(array $rules, $type = '') |
||||||
168 | { |
||||||
169 | return ValidateHelper::instance() |
||||||
170 | ->init($rules, $type); |
||||||
0 ignored issues
–
show
The method
init() does not exist on DtApp\ThinkLibrary\Helper . Since it exists in all sub-types, consider adding an abstract or default implementation to DtApp\ThinkLibrary\Helper .
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||||
171 | } |
||||||
172 | |||||||
173 | /** |
||||||
174 | * 获取解密后的数据 |
||||||
175 | * @param string $name |
||||||
176 | * @param null $default |
||||||
0 ignored issues
–
show
|
|||||||
177 | * @return mixed |
||||||
178 | */ |
||||||
179 | public function getAesDecryptData(string $name = '', $default = null) |
||||||
180 | { |
||||||
181 | if (empty($name)) { |
||||||
182 | return $this->aes_decrypt_data; |
||||||
183 | } |
||||||
184 | |||||||
185 | return $this->aes_decrypt_data[$name] ?? $default; |
||||||
186 | } |
||||||
187 | |||||||
188 | /** |
||||||
189 | * 验证接口签名 |
||||||
190 | */ |
||||||
191 | public function _judgeSign() |
||||||
192 | { |
||||||
193 | // 加密的数据参数 |
||||||
194 | $aes = $this->request->post('aes', ''); |
||||||
195 | if (empty($aes)) { |
||||||
196 | $this->error('数据未签名!', 104); |
||||||
197 | } |
||||||
198 | // 获取时间数据 |
||||||
199 | $timestamp = $this->request->get('timestamp', 0); |
||||||
200 | // 判断是否有时间 |
||||||
201 | if (empty($timestamp)) { |
||||||
202 | $this->error('数据异常!', 105); |
||||||
203 | } |
||||||
204 | // 解密 |
||||||
205 | $aes_decode = $this->decrypt($aes, $timestamp); |
||||||
0 ignored issues
–
show
It seems like
$aes can also be of type object ; however, parameter $data of DtApp\ThinkLibrary\ApiController::decrypt() does only seem to accept string , maybe add an additional type check?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() It seems like
$timestamp can also be of type object ; however, parameter $timestamp of DtApp\ThinkLibrary\ApiController::decrypt() does only seem to accept integer , maybe add an additional type check?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||||
206 | if (empty($aes_decode)) { |
||||||
207 | $this->error('解密失败', 106); |
||||||
208 | } |
||||||
209 | $data = json_decode($aes_decode, true); |
||||||
210 | // 判断是不是小于服务器时间 |
||||||
211 | $before = strtotime('-2minute'); |
||||||
212 | $rear = strtotime('+2minute'); |
||||||
213 | if ($timestamp <= $rear && $timestamp >= $before) { |
||||||
214 | $this->aes_decrypt_data = $data; |
||||||
215 | } else { |
||||||
216 | $this->error('已超时,请重新尝试!'); |
||||||
217 | } |
||||||
218 | } |
||||||
219 | |||||||
220 | /** |
||||||
221 | * 加密 |
||||||
222 | * @param $data |
||||||
223 | * @param int $timestamp |
||||||
224 | * @return bool|string |
||||||
225 | */ |
||||||
226 | private function encrypt($data, int $timestamp) |
||||||
227 | { |
||||||
228 | if (empty($this->aes_md5)) { |
||||||
229 | $this->setAesMd5(); |
||||||
230 | } |
||||||
231 | if (empty($this->aes_md5_iv)) { |
||||||
232 | $this->setAesMd5Iv(); |
||||||
233 | } |
||||||
234 | if (!empty(is_array($data))) { |
||||||
235 | $data = json_encode($data); |
||||||
236 | } |
||||||
237 | return urlencode(base64_encode(openssl_encrypt($data, 'AES-128-CBC', $this->aes_md5, 1, $this->aes_md5_iv . $timestamp))); |
||||||
0 ignored issues
–
show
It seems like
$this->aes_md5 can also be of type boolean ; however, parameter $passphrase of openssl_encrypt() does only seem to accept string , maybe add an additional type check?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||||
238 | } |
||||||
239 | |||||||
240 | /** |
||||||
241 | * 解密 |
||||||
242 | * @param string $data |
||||||
243 | * @param int $timestamp |
||||||
244 | * @return bool|false|string |
||||||
245 | */ |
||||||
246 | private function decrypt(string $data, int $timestamp) |
||||||
247 | { |
||||||
248 | if (empty($this->aes_md5)) { |
||||||
249 | $this->setAesMd5(); |
||||||
250 | } |
||||||
251 | if (empty($this->aes_md5_iv)) { |
||||||
252 | $this->setAesMd5Iv(); |
||||||
253 | } |
||||||
254 | return openssl_decrypt(base64_decode(urldecode($data)), "AES-128-CBC", $this->aes_md5, true, $this->aes_md5_iv . $timestamp); |
||||||
0 ignored issues
–
show
true of type true is incompatible with the type integer expected by parameter $options of openssl_decrypt() .
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() It seems like
$this->aes_md5 can also be of type boolean ; however, parameter $passphrase of openssl_decrypt() does only seem to accept string , maybe add an additional type check?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||||
255 | } |
||||||
256 | } |
||||||
257 |
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.