介绍
您可以使用2个简单的方法
您也可以通过使用令牌的认证和使用结合两者验证邮件发送完整性的签名
认证令牌
如果你要考虑在数据库匹配任何识别或许你可以考虑创建认证令牌,而不是用户ID,会话,饼干,IP,时间戳,等等!如建议。
创建一个随机令牌,并保存到数据库
$token = bin2hex(mcrypt_create_iv(64, MCRYPT_DEV_URANDOM));
- 这可以很容易产生
- 可以保证它不像密码猜测更加困难
- 如果损害它可以很容易地被删除,重新生成另一个密钥
签署请求
这个概念很简单,对于每一个文件上传必须肉类使用随机产生的密钥就像令牌,每个特定用户
这可以很容易地HMAC实现与hash_hmac_file
功能的特定签名装箱
结合两种认证&签名的请求
这里是概念的一个简单的教授
服务器1
/**
* This should be stored securly
* Only known to User
* Unique to each User
* Eg : mcrypt_create_iv(32, MCRYPT_DEV_URANDOM);
*/
$key = "d767d183315656d90cce5c8a316c596c971246fbc48d70f06f94177f6b5d7174";
$token = "3380cb5229d4737ebe8e92c1c2a90542e46ce288901da80fe8d8c456bace2a9e";
$url = "http://server 2/run.php";
// Start File Upload Manager
$request = new FileManager($key, $token);
// Send Multiple Files
$responce = $request->send($url, [
"file1" => __DIR__ . "/a.png",
"file2" => __DIR__ . "/b.css"
]);
// Decode Responce
$json = json_decode($responce->data, true);
// Output Information
foreach($json as $file) {
printf("%s - %s \n", $file['name'], $file['msg']);
}
输出
temp\14-a.png - OK
temp\14-b.css - OK
服务器2
// Where to store the files
$tmpDir = __DIR__ . "/temp";
try {
$file = new FileManager($key, $token);
echo json_encode($file->recive($tmpDir), 128);
} catch (Exception $e) {
echo json_encode([
[
"name" => "Execption",
"msg" => $e->getMessage(),
"status" => 0
]
], 128);
}
类用于
分
class FileManager {
private $key;
function __construct($key, $token) {
$this->key = $key;
$this->token = $token;
}
function send($url, $files) {
$post = [];
// Convert to array fromat
$files = is_array($files) ? $files : [
$files
];
// Build Post Request
foreach($files as $name => $file) {
$file = realpath($file);
if (! (is_file($file) || is_readable($file))) {
throw new InvalidArgumentException("Invalid File");
}
// Add File
$post[$name] = "@" . $file;
// Sign File
$post[$name . "-sign"] = $this->sign($file);
}
// Start Curl ;
$ch = curl_init($url);
$options = [
CURLOPT_HTTPHEADER => [
"X-TOKEN:" . $this->token
],
CURLOPT_RETURNTRANSFER => 1,
CURLOPT_POST => count($post),
CURLOPT_POSTFIELDS => $post
];
curl_setopt_array($ch, $options);
// Get Responce
$responce = [
"data" => curl_exec($ch),
"error" => curl_error($ch),
"error" => curl_errno($ch),
"info" => curl_getinfo($ch)
];
curl_close($ch);
return (object) $responce;
}
function recive($dir) {
if (! isset($_SERVER['HTTP_X_TOKEN'])) {
throw new ErrorException("Missing Security Token");
}
if ($_SERVER['HTTP_X_TOKEN'] !== $this->token) {
throw new ErrorException("Invalid Security Token");
}
if (! isset($_FILES)) {
throw new ErrorException("File was not uploaded");
}
$responce = [];
foreach($_FILES as $name => $file) {
$responce[$name]['status'] = 0;
// check if file is uploaded
if ($file['error'] == UPLOAD_ERR_OK) {
// Check for signatire
if (isset($_POST[$name . '-sign']) && $_POST[$name . '-sign'] === $this->sign($file['tmp_name'])) {
$path = $dir . DIRECTORY_SEPARATOR . $file['name'];
$x = 0;
while(file_exists($path)) {
$x ++;
$path = $dir . DIRECTORY_SEPARATOR . $x . "-" . $file['name'];
}
// Move File to temp folder
move_uploaded_file($file['tmp_name'], $path);
$responce[$name]['name'] = $path;
$responce[$name]['sign'] = $_POST[$name . '-sign'];
$responce[$name]['status'] = 1;
$responce[$name]['msg'] = "OK";
} else {
$responce[$name]['msg'] = sprintf("Invalid File Signature");
}
} else {
$responce[$name]['msg'] = sprintf("Upload Error : %s" . $file['error']);
}
}
return $responce;
}
private function sign($file) {
return hash_hmac_file("sha256", $file, $this->key);
}
}
其他的事情要考虑
为了更安全,你可以考虑跟随
- IP锁定
- 文件大小限制
- 文件类型验证
- 公开 - 密钥密码学
- 更改日期基于令牌生成
结论
样本类可以在很多方面进行扩展和,而不是使用网址,你可以考虑适当json RCP
解决
OAuth2可能是一个解决方案 – 2013-06-24 05:12:06
您可以配置服务器2,以便只有服务器1可以访问其上的文件。 现在,服务器1应该负责认证用户。即登录用户并决定他可以访问哪些文件。 –
如果没有开放赏金,我会投票结束。我可以考虑至少12个适合传输文件的协议以及几种处理认证,授权和会话管理的方法。你没有提到任何对实现和安全模型的限制。支付网关有什么与文件传输有关的? – symcbean