Saya memiliki sistem (aplikasi berbasis web) yang menarik lampiran file dari sistem pihak ke-3 melalui SOAP. Ini pada gilirannya pada sistem kami dibuat sebagai file dalam direktori.
Ketika pengguna sistem (dikonfirmasi melalui ldap) membuat permintaan ke aplikasi saya untuk mengambil salah satu dari lampiran ini:
1. I request it via soap
2. Process the response to build the file on our system
3. Redirect user to the location so they can download the file.
Pertama, apakah ini pendekatan yang baik?
Apakah ada cara yang lebih baik untuk menyajikan file yang tidak akan berada di server banyak setelah unduhan lampiran (cron job akan membersihkan direktori begitu sering)?
Kedua, apakah ada cara saya bisa melayani file melalui apache tanpa menyimpannya di root web?
Ketiga, bagaimana cara menegakkan izin pada file-file ini sehingga tidak sembarang pengguna dapat mengunduh sembarang lampiran?
Pengaturan kami:
linux
apache
php - soap libraries for communication
seperate LDAP for authentication
3rd party soap server (where attachments come from)
EDIT: Kode untuk melayani lampiran jika ada yang penasaran.
<?php
ini_set('display_errors',1);
error_reporting(E_ALL|E_STRICT);
//require global definitions
require_once("includes/globals.php");
//validate the user before continuing
isValidUser();
$subTitle = "Attachment";
$attachmentPath = "/var/www/html/DEVELOPMENT/serviceNow/selfService/uploads/";
if(isset($_GET['id']) and !empty($_GET['id'])){
//first lookup attachment meta information
$a = new Attachment();
$attachment = $a->get($_GET['id']);
//filename will be original file name with user name.n prepended
$fileName = $attachmentPath.$_SESSION['nameN'].'-'.$attachment->file_name;
//instantiate new attachmentDownload and query for attachment chunks
$a = new AttachmentDownload();
$chunks= $a->getRecords(array('sys_attachment'=>$_GET['id'], '__order_by'=>'position'));
$fh = fopen($fileName.'.gz','w');
// read and base64 encode file contents
foreach($chunks as $chunk){
fwrite($fh, base64_decode($chunk->data));
}
fclose($fh);
//open up filename for writing
$fh = fopen($fileName,'w');
//open up filename.gz for extraction
$zd = gzopen($fileName.'.gz', "r");
//iterate over file and write contents
while (!feof($zd)) {
fwrite($fh, gzread($zd, 60*57));
}
fclose($fh);
gzclose($zd);
unlink($fileName.'.gz');
$info = pathinfo($fileName);
header('Content-Description: File Transfer');
header('Content-Type: '.Mimetypes::get($info['extension']));
header('Content-Disposition: attachment; filename=' . basename($fileName));
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Pragma: public');
header('Content-Length: ' . filesize($fileName));
ob_clean();
flush();
readfile($fileName);
exit();
}else{
header("location: ".$links['status']."?".urlencode("item=incident&action=view&status=-1&place=".$links['home']));
}
?>
Jawaban:
Kedengarannya baik bagi saya. Pastikan Anda mengautentikasi pengguna sebelum melalui semua itu.
Letakkan file di luar webroot. Kemudian menggunakan PHP lulus file melalui skrip. Dengan begitu tidak ada yang bisa menautkan ke file secara langsung dan memotong kontrol Anda. (Secara alami pastikan skrip yang melakukan ini hanya setelah memverifikasi pengguna memiliki izin untuk mengambil file itu).
Contoh PHP:
Buat pengguna masuk untuk mengambil file mereka. Kemudian Anda dapat mengatur variabel sesi yang mengidentifikasi mereka sebagai diizinkan untuk diunduh. Pastikan skrip Anda mengautentikasi mereka di setiap halaman proses ini.
sumber