PHP如何改造Vue项目中的API解码文件?
前后端开发时,往往由后端提供API,且该API需要经过一些Header或者Token设置,方能正确请求并解码参数,此方法既能保护API不被暴露,也能一定程度保护项目不被恶意逆向破解,影响运行。
前端即可采用Vue也可以采用PHP的方式,两种解码所需参数都一样,但都有各自的处理方式,
Vue的处理的方式如,(核心处理):
// request 拦截器 // 可以自请求发送前对请求做一些处理 // 比如统一加token,对请求参数统一加密 request.interceptors.request.use((config) => { console.log(navigator.userAgent); if (config.url.indexOf("notMask") === -1) { // store.commit('requestBegin'); } const deviceId = encryptPassword(getUniqueDeviceIdentifier()); const authToken = localStorage.getItem('authToken') || ''; const ts = new Date().getTime(); const token = handleLocalStorage('get', 'HLJXCXTOKEN') // 设置请求头 // 优先使用用户传入的 Content-Type,否则使用默认值 if (!config.headers['Content-Type']) { config.headers['Content-Type'] = 'application/json;charset=utf-8'; } config.headers["accesskey"] = "q878s0"; //请求头签名 config.headers["pId"] = handleLocalPID() //从缓存中获取语言 config.headers['lang'] = handleLangType()==='zh' ? 'zh' : handleLangType() config.headers['countryCode'] = 'ZH-CN' config.headers['channel'] = 'WEBH5' config.headers['version'] = '1.0.01' config.headers['system'] = 'WEBH5' // config.headers['timezone'] = 'UTC/GMT+08:00' config.headers['timezone'] = '8' config.headers['platform'] = PLATFORM() config.headers['versionCode'] = '1.0.01' config.headers['deviceToken'] = 'WEBH5' config.headers['phonesystem'] = 'WEBH5' config.headers['deviceId'] = deviceId config.headers['idfa'] = '' config.headers['oaid'] = '' config.headers['appmarketid'] = '' config.headers['authToken'] = authToken config.headers['ts'] = ts // 设置签名 if (config.url) { config.headers['sign'] = sign(config.url, deviceId, ts) } // 设置token if (token) { config.headers['authToken'] = token } return config }, (error) => { // store.commit('requestComplete'); console.error(" 请求失败,服务器错误"); return Promise.reject(error); });
// response 拦截器 // 可以在接口响应后统一处理结果 request.interceptors.response.use(async (response) => { // store.commit('requestComplete'); let res = response.data; // 兼容服务端返回的字符串数据 if (typeof res === "string") { res = res ? JSON.parse(res) : res; } else { if (res.data == null || res.data === "") { res.data = null; } else { // console.log(res.data); let bb = requestDecrypt(res.data); const gzipData = atob(bb) .split("") .map((char) => char.charCodeAt(0)); const gzipArray = new Uint8Array(gzipData); const uncompressedData = pako.inflate(gzipArray); res.data = new TextDecoder().decode(uncompressedData); res.data = JSON.parse(res.data); } switch (res.code) { case 1013: //移除Token localStorage.removeItem('authToken'); //移除用户信息 localStorage.removeItem('USER_PROFILE'); return; } } return res; }, (error) => { // store.commit('requestComplete'); console.error(" 请求失败,服务器错误"); return Promise.reject(error); } );
PHP的处理的方式如,(核心处理):
<?php /** * Request proxy wrapper for theme templates. * * 说明:集中封装访问远端 VDAPI 服务时的公共逻辑: * - 组装设备信息 / 签名 * - 构建统一请求头 * - 调用 wp_remote_request 并处理错误 * - 对响应数据执行解密与解析 */ require_once get_template_directory() . '/api/Function.php'; class RequestProxy { /** 默认目标服务 base url */ private const DEFAULT_TARGET_BASE = 'http://apitest.xxxx.cc'; /** @var string */ private $targetBase; public function __construct(?string $targetBase = null) { $base = $targetBase ?: self::DEFAULT_TARGET_BASE; $this->targetBase = rtrim($base, '/'); } /** * 对指定 path 发起 GET 请求,并返回统一结构。 * * @param string $path 目标接口路径(可含 query) * @param string $deviceIdRaw 客户端 base64 原文(可为空) * @param array $extraHeaders 额外 header * @return array */ public function get(string $path, string $deviceIdRaw = '', array $extraHeaders = []): array { $path = $this->normalizePath($path); $forwardUrl = $this->targetBase . $path; $deviceId = $this->resolveDeviceId($deviceIdRaw); $ts = (string) round(microtime(true) * 1000); $sign = RequestHelper::sign($path, $deviceId, $ts, 'm94icx7kiq67'); $headers = $this->buildHeaders($deviceId, $ts, $sign, $extraHeaders); $response = wp_remote_request($forwardUrl, [ 'method' => 'GET', 'headers' => $headers, 'timeout' => 30, ]); if (is_wp_error($response)) { return [ 'code' => 1, 'msg' => 'request_error', 'data' => [ 'error' => $response->get_error_message(), 'debug' => ['deviceId' => $deviceId, 'ts' => $ts, 'sign' => $sign], ], 'currentTime' => (int) $ts, ]; } $code = wp_remote_retrieve_response_code($response); $body = wp_remote_retrieve_body($response); return RequestHelper::parseAndDecryptResponse($body, $deviceId, $ts, $sign); } /** * 对指定 path 发起 POST 请求,并返回统一结构。 * * @param string $path 目标接口路径(可含 query) * @param string $deviceIdRaw 客户端 base64 原文(可为空) * @param array $extraHeaders 额外 header * @param array $postData POST 数据(将作为 JSON 发送) * @return array */ public function post(string $path, string $deviceIdRaw = '', array $extraHeaders = [], array $postData = []): array { $path = $this->normalizePath($path); $forwardUrl = $this->targetBase . $path; $deviceId = $this->resolveDeviceId($deviceIdRaw); $ts = (string) round(microtime(true) * 1000); $sign = RequestHelper::sign($path, $deviceId, $ts, 'm94icx7kiq67'); $headers = $this->buildHeaders($deviceId, $ts, $sign, $extraHeaders); $response = wp_remote_request($forwardUrl, [ 'method' => 'POST', 'headers' => $headers, 'body' => json_encode($postData, JSON_UNESCAPED_UNICODE), 'timeout' => 30, ]); if (is_wp_error($response)) { return [ 'code' => 1, 'msg' => 'request_error', 'data' => [ 'error' => $response->get_error_message(), 'debug' => ['deviceId' => $deviceId, 'ts' => $ts, 'sign' => $sign], ], 'currentTime' => (int) $ts, ]; } $code = wp_remote_retrieve_response_code($response); $body = wp_remote_retrieve_body($response); return RequestHelper::parseAndDecryptResponse($body, $deviceId, $ts, $sign); } /** * 便捷方法:发起 GET 请求(自动处理 deviceId),类似于 JS 的 requestGetList。 * * @param string $path 目标接口路径(可含 query) * @param array $extraHeaders 额外 header * @return array */ public function requestGetList(string $path, array $extraHeaders = []): array { return $this->get($path, '', $extraHeaders); } /** * 便捷方法:发起 POST 请求(自动处理 deviceId),类似于 JS 的 requestPostList。 * * @param string $path 目标接口路径(可含 query) * @param array $extraHeaders 额外 header * @param array $postData POST 数据(将作为 JSON 发送) * @return array */ public function requestPostList(string $path, array $extraHeaders = [], array $postData = []): array { return $this->post($path, '', $extraHeaders, $postData); } private function buildHeaders(string $deviceId, string $ts, string $sign, array $extra = []): array { $baseHeaders = [ 'Accept' => 'application/json, text/plain, */*', 'Content-Type' => 'application/json;charset=utf-8', 'accesskey' => 'q878s0', 'pId' => 'lVFFFvztVU', 'lang' => 'zh', 'countryCode' => 'ZH-CN', 'channel' => 'WEBH5', 'version' => '1.0.01', 'system' => 'WEBH5', 'timezone' => '8', 'platform' => 'WEBH5', 'versionCode' => '1.0.01', 'deviceToken' => 'WEBH5', 'phonesystem' => 'WEBH5', 'deviceId' => $deviceId, 'idfa' => '', 'oaid' => '', 'appmarketid' => '', 'authToken' => '', 'ts' => $ts, 'sign' => $sign, 'X-Ts' => $ts, 'X-Device' => $deviceId, 'X-Sign' => $sign, ]; return array_merge($baseHeaders, $extra); } private function normalizePath(string $path): string { $path = trim($path); if ($path === '') { $path = '/'; } if ($path[0] !== '/') { $path = '/' . $path; } return $path; } private function resolveDeviceId(string $deviceIdRaw): string { $deviceIdRaw = trim($deviceIdRaw); if ($deviceIdRaw !== '') { return md5($deviceIdRaw); } $host = gethostname(); $serverAddr = $_SERVER['SERVER_ADDR'] ?? '127.0.0.1'; return md5($host . '-' . $serverAddr); } }

浙公网安备 33010602011771号