39 lines
1.5 KiB
PHP
39 lines
1.5 KiB
PHP
<?php
|
||
/**
|
||
* DWG/DXF 查看器 - 令牌接口
|
||
* 同源校验 + HMAC 短时令牌(5 分钟)。与 STEPViewer 的 api/token.php 同一套设计。
|
||
* 部署前务必改掉 SECRET。
|
||
*/
|
||
header('Content-Type: application/json; charset=utf-8');
|
||
header('Cache-Control: no-store');
|
||
|
||
$SECRET = 'be323d1b90bd2fda624083d4d1d716b7';
|
||
$TTL = 300;
|
||
|
||
function json_out($code, $obj) {
|
||
http_response_code($code);
|
||
echo json_encode($obj, JSON_UNESCAPED_UNICODE);
|
||
exit;
|
||
}
|
||
|
||
$f = $_GET['f'] ?? '';
|
||
if (!$f || !preg_match('/\.(dwg|dxf|enc)$/i', $f)) json_out(400, ['error' => 'bad file']);
|
||
if (strpos($f, '..') !== false) json_out(400, ['error' => 'bad path']);
|
||
|
||
// 只允许本站页面来取令牌,挡掉直接爬取。
|
||
// 优先看 Sec-Fetch-Site:由查看器页面发起的同源 fetch 恒为 same-origin(跨站 iframe
|
||
// 嵌入也不受影响,且不会被父站点的 Referrer-Policy 剥掉);没有该头的旧浏览器
|
||
// 退回「Referer 含本站 host」的校验。直链/curl 两种都过不了。
|
||
$fetchSite = $_SERVER['HTTP_SEC_FETCH_SITE'] ?? '';
|
||
$referer = $_SERVER['HTTP_REFERER'] ?? '';
|
||
$host = $_SERVER['HTTP_HOST'] ?? '';
|
||
if ($fetchSite !== '') {
|
||
if ($fetchSite !== 'same-origin' && $fetchSite !== 'same-site') json_out(403, ['error' => 'forbidden']);
|
||
} elseif (!$host || strpos($referer, $host) === false) {
|
||
json_out(403, ['error' => 'forbidden']);
|
||
}
|
||
|
||
$exp = time() + $TTL;
|
||
$sig = substr(hash_hmac('sha256', $f . '|' . $exp, $SECRET), 0, 16);
|
||
json_out(200, ['token' => $sig, 'expires' => $exp]);
|