验证访问令牌并将下载重定向到另一台服务器
Verify access token and redirect the download to another server
我有一个 Server A
,它有一个有效下载令牌的数据库。
如果用户提供有效令牌(存在于数据库中),他们将可以下载一个大文件(> 2 GB)。目前,我这样做(详见Fastest Way to Serve a File Using PHP and ):
<?php
$ok = check_token_in_database($_GET['token']); // internally uses a SQLite DB
$file = "bigfile.zip";
if ($ok) {
header("X-Sendfile: /path/to/" . $file);
header("Content-type: application/octet-stream");
header('Content-Disposition: attachment; filename="' . $file . '"');
}
有效,但现在我需要减轻 Server A
的负载,如果令牌有效,我想从另一个服务器提供文件Server B
。我在想:
<?php
$ok = check_token_in_database($_GET['token']);
if ($ok) {
header("Location: https://server_b.example.com/obfuscated_url_ff87a45d76apZ/bigfile.zip");
但是,任何人都可能找到目的地link https://server_b.example.com/obfuscated_url_ff87a45d76apZ/bigfile.zip
他们可以与其他人分享,这是我不想要的。
如何处理这种情况,而不必将令牌数据库和令牌检查移动到 Server B
?
您可以使用 JWT 生成令牌。在负载中,您可以存储用户的 IP 地址以防止 link 共享。
我不确定 PHP 使用哪个库,但让我们以这个为例:
https://github.com/miladrahimi/php-jwt
在服务器 A 上生成令牌:
// Use HS256 to generate and parse tokens
$signer = new HS256(JWT_SECRET_KEY);
// Generate a token
$generator = new Generator($signer);
$jwt = $generator->generate(['file' => 'bigfile.zip', 'ip' => $_SERVER['REMOTE_ADDR']);
在服务器 B 中,您验证并解析令牌:
$jwt = &$_GET['token'];
$signer = new HS256(JWT_SECRET_KEY);
// Add Validation (Extend the DefaultValidator)
$validator = new DefaultValidator();
$validator->addRule('ip', new EqualsTo($_SERVER['REMOTE_ADDR']));
// Parse the token
$parser = new Parser($signer);
try {
$claims = $parser->parse($jwt);
// Serve $claims['file'] here.
} catch (ValidationException $e) {
// Validation failed.
}
在两台服务器中,您都应该定义密钥:
define('JWT_SECRET_KEY', 'your-long-secret-key-here');
当然,您可以添加更多验证、令牌过期等。
如果只想将私钥保存在服务器A上,则应使用RSA算法,然后在服务器A上使用私钥生成令牌,并在服务器B上使用[=30解析令牌=] 键。 (图书馆的自述文件中有一个例子)
我有一个 Server A
,它有一个有效下载令牌的数据库。
如果用户提供有效令牌(存在于数据库中),他们将可以下载一个大文件(> 2 GB)。目前,我这样做(详见Fastest Way to Serve a File Using PHP and
<?php
$ok = check_token_in_database($_GET['token']); // internally uses a SQLite DB
$file = "bigfile.zip";
if ($ok) {
header("X-Sendfile: /path/to/" . $file);
header("Content-type: application/octet-stream");
header('Content-Disposition: attachment; filename="' . $file . '"');
}
有效,但现在我需要减轻 Server A
的负载,如果令牌有效,我想从另一个服务器提供文件Server B
。我在想:
<?php
$ok = check_token_in_database($_GET['token']);
if ($ok) {
header("Location: https://server_b.example.com/obfuscated_url_ff87a45d76apZ/bigfile.zip");
但是,任何人都可能找到目的地link https://server_b.example.com/obfuscated_url_ff87a45d76apZ/bigfile.zip
他们可以与其他人分享,这是我不想要的。
如何处理这种情况,而不必将令牌数据库和令牌检查移动到 Server B
?
您可以使用 JWT 生成令牌。在负载中,您可以存储用户的 IP 地址以防止 link 共享。
我不确定 PHP 使用哪个库,但让我们以这个为例: https://github.com/miladrahimi/php-jwt
在服务器 A 上生成令牌:
// Use HS256 to generate and parse tokens
$signer = new HS256(JWT_SECRET_KEY);
// Generate a token
$generator = new Generator($signer);
$jwt = $generator->generate(['file' => 'bigfile.zip', 'ip' => $_SERVER['REMOTE_ADDR']);
在服务器 B 中,您验证并解析令牌:
$jwt = &$_GET['token'];
$signer = new HS256(JWT_SECRET_KEY);
// Add Validation (Extend the DefaultValidator)
$validator = new DefaultValidator();
$validator->addRule('ip', new EqualsTo($_SERVER['REMOTE_ADDR']));
// Parse the token
$parser = new Parser($signer);
try {
$claims = $parser->parse($jwt);
// Serve $claims['file'] here.
} catch (ValidationException $e) {
// Validation failed.
}
在两台服务器中,您都应该定义密钥:
define('JWT_SECRET_KEY', 'your-long-secret-key-here');
当然,您可以添加更多验证、令牌过期等。
如果只想将私钥保存在服务器A上,则应使用RSA算法,然后在服务器A上使用私钥生成令牌,并在服务器B上使用[=30解析令牌=] 键。 (图书馆的自述文件中有一个例子)