Issues (1482)

src/ApiController.php (9 issues)

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
Documentation Bug introduced by
It seems like $value can also be of type boolean. However, the property $aes_md5 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 $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account 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.

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;
}
Loading history...
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
Documentation Bug introduced by
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 $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account 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.

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;
}
Loading history...
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 ignore-call  annotation

170
            ->/** @scrutinizer ignore-call */ init($rules, $type);
Loading history...
171
    }
172
173
    /**
174
     * 获取解密后的数据
175
     * @param string $name
176
     * @param null $default
0 ignored issues
show
Documentation Bug introduced by
Are you sure the doc-type for parameter $default is correct as it would always require null to be passed?
Loading history...
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 ignore-type  annotation

205
        $aes_decode = $this->decrypt(/** @scrutinizer ignore-type */ $aes, $timestamp);
Loading history...
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 ignore-type  annotation

205
        $aes_decode = $this->decrypt($aes, /** @scrutinizer ignore-type */ $timestamp);
Loading history...
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 ignore-type  annotation

237
        return urlencode(base64_encode(openssl_encrypt($data, 'AES-128-CBC', /** @scrutinizer ignore-type */ $this->aes_md5, 1, $this->aes_md5_iv . $timestamp)));
Loading history...
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 ignore-type  annotation

254
        return openssl_decrypt(base64_decode(urldecode($data)), "AES-128-CBC", $this->aes_md5, /** @scrutinizer ignore-type */ true, $this->aes_md5_iv . $timestamp);
Loading history...
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 ignore-type  annotation

254
        return openssl_decrypt(base64_decode(urldecode($data)), "AES-128-CBC", /** @scrutinizer ignore-type */ $this->aes_md5, true, $this->aes_md5_iv . $timestamp);
Loading history...
255
    }
256
}
257