Issues (1482)

src/ApiController.php (1 issue)

Labels
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;
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;
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
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);
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)));
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);
255
    }
256
}
257