Passed
Push — v6 ( 515a76...c4922d )
by 光春
05:09
created

ApiController::setAesMd5()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 3
c 0
b 0
f 0
dl 0
loc 5
rs 10
cc 1
nc 1
nop 1
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;
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...
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;
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...
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);
0 ignored issues
show
Bug introduced by
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

173
            ->/** @scrutinizer ignore-call */ init($rules, $type);
Loading history...
174
    }
175
176
    /**
177
     * 获取解密后的数据
178
     * @param string $name
179
     * @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...
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);
0 ignored issues
show
Bug introduced by
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

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

208
        $aes_decode = $this->decrypt(/** @scrutinizer ignore-type */ $aes, $timestamp);
Loading history...
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);
0 ignored issues
show
Bug introduced by
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

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