Pages

Search This Blog

Download dengan Hak Akses di PHP

Script ini terinspirasi saat saya download file pada sebuah sistem e-learning pada sebuah situs. Kala itu saya ingin mendownload sebuah file berupa document word. Link memang tersedia tetapi ternyata file tidak bisa di download. Namun ketika saya lakukan direct access dengan meng-copy link dimana file tersebut berada di server pada address bar browser, viola, saya dapatkan file-nya. Lantas saya berfikir, Kalau begitu user yang tidak terdaftarpun bisa mendownload file tersebut. Bagaimana cara agar hal tersebut bisa dicegah?
Saya akan berbagi cara membuat script download dengan batasan hak akses hanya pada user yang login ke dalam sistem tersebut saja yang bisa download file tersebut. Jadi user yang tidak login tidak bisa download. Pertama kita buat database terlebih dahulu dengan nama download. Lalu buat 2 table dengan nama user dan file. Berikut SQL-nya:

CREATE TABLE `file` (
  `id` varchar(32) NOT NULL,
  `file_name` varchar(100) NOT NULL,
  `type` varchar(100) NOT NULL,
  PRIMARY KEY  (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

--
-- Dumping data for table `file`
-- 

-- --------------------------------------------------------

--
-- Table structure for table `user`
-- 

CREATE TABLE `user` (
  `username` varchar(100) NOT NULL,
  `password` varchar(100) NOT NULL,
  PRIMARY KEY  (`username`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

--
-- Dumping data for table `user`
-- 

INSERT INTO `user` VALUES ('oki', '123');

Tabel User dibuat untuk menampung data user yang boleh melakukan download. Pada contoh kali ini terdapat dua field, yakni  username dan  password. Kita isi terlebih dahulu datanya dengan username oki dan passwroord 123. Tabel file dibuat untuk menampung data file yang kita upload. Terdiri dari 3 field, id, file_name untuk menampung nama file dan type untuk menyimpan tipe file. Field id terdiri dari 32 karakter terenkripsi. Sebenarnya bisa menggunakan integer dengan Autoincreament, tapi nanti saya akan jelaskan kenapa saya menggunakan varchar dengan panjang 32 karakter. Selanjutnya kita buat folder 'uploads' pada root aplikasi kita. Ini digunakan untuk menyimpan file hasil upload kita nanti. Setelah itu kita buat file koneksi.php untuk menghubungkan aplikasi yang akan kita buat dengan server.

<?php

define('HOST','localhost');

define('USERNAME','root');

define('PASSWORD','');

define('DATABASE','download');

mysql_connect(HOST,USERNAME,PASSWORD);

mysql_select_db(DATABASE);

?>

Ganti kata root pada define('USERNAME','root') dengan username pada localhost Anda. Juga isikan password untuk akses localhost pada baris define('PASSWORD','password_anda'). Kita buat form untuk login. Buat sebuah file php dengan nama form_login.php.

<form action="login.php" method="post">
        <table width="269">
          <tr>
            <td width="192">Username</td>
          </tr>
    <tr>
            <td><input name="username" type="text" id="username" class="text" /></td>
          </tr>
          <tr>
            <td>Password</td>
          </tr><tr>
            <td><input name="password" type="password" id="password" class="text" /></td>
          </tr>
        </table><input type="submit" class="btn_blue" name="btLogin" id="btLogin" value="Login" />
        </form>

Ok, jika sudah kita buat skript untuk menangani login. Kita buat lagi dengan nama login.php.

<?php
session_start();//fungsi session digunakan setiap kali akan menggunakan variable $_SESSION
include('koneksi.php');

$username = $_POST['username'];
$password = $_POST['password'];

$query = mysql_query("SELECT * FROM user WHERE username='$username' AND password ='$password'")or die(mysql_error());

if( mysql_num_rows($query) >0 ){
 $_SESSION['uname'] = 'yes';
 header('location:index.php');
}else{
 echo "maaf user nggak ada.";
}

?>

Logikanya sederhana, Jika terdapat username dan password seperti yang kita input pada Form login maka buat variable session $_SESSION['uname'] dengan isi 'yes' lalu alihkan ke index.php, jika tidak ada tampilkan tulisan "Maaf, User nggak ada". Selanjtunya, kita buat file index.php. Skrip-nya sebagai berikut:

<?php
session_start();
if(isset($_SESSION['uname'])){
include('koneksi.php');
include('form_upload.php');

}else{
include('form_login.php');
}

?>

Logikanya jika ada variable $_SESSION['uname'] maka sertakan (include) file koneksi.php dan tampilkan form untuk upload file. Jika tidak ada maka tampilkan Form login. Jadi index.php dimaksudkan agar jika user belum melakukan login, sistem akan menampilkan form login, jika sudah maka akan ditampilkan form upload. Langkah selanjutnya yaitu membuat form upload. Buat file dengan nama form_upload.php dengan skrip  sebagai berikut:

<form action="upload.php" method="post" enctype="multipart/form-data">
<table width="269">
<tr>
<td width="192">File</td>
<td><input name="berkas" type="file" /></td>
</tr>
</table><input type="submit" value="Upload" />
</form>
Jika sudah,  buat lagi file dengan nama upload.php. File ini berfungsi untuk memproses upload.
<?php
include('koneksi.php');
$uploads_dir = 'uploads';
$name = $_FILES['berkas']['name'];
$id = md5($name);
move_uploaded_file($_FILES['berkas']['tmp_name'], "$uploads_dir/$name");

$query = mysql_query("INSERT INTO file(id, file_name, type) VALUES('$id','$name', '".$_FILES['berkas']['type']."')");

header('location: index.php');

?>

$uploads_dir diisi dengan nama  direktori yang kita telah buat sebelumnya, yaitu folder uploads. Kita menggunakan fungsi move_uploaded_file()untuk  mengupload file yang kita submit dari form upload. Ok, Sekarang Anda sudah bisa melakukan upload file. Data file juga akan masuk ke dalam database table file dan file hasil upload juga akan berada  pada folder uploads. Lho? downloadnya gimana, Mas? Sabar, sabar. Mari kita buat aplikasi downloadnya. Pertama kita buat terlebih dahulu file untuk menampilkan data file yang sudah kita upload ke database. Buat file dengan nama list_file.php.

<?php
$query = mysql_query("SELECT * FROM file");
while($data = mysql_fetch_array($query) ){
 echo '<a href="download.php?file='.$data['file_name'].'&type='.$data['type'].'">'.$data['file_name'].'</a>';
 echo "<br>";
}
?>

Setelah selesai kita modifikasi sedikit file index.php yang kita buat sebelumnya menjadi seperti berikut:

<?php
session_start();
if(isset($_SESSION['uname'])){
include('koneksi.php');
include('list_file.php');//untuk menampilkan list file
include('form_upload.php');

}else{
include('form_login.php');
}

?>

Jika kita buka index.php kita akan melihat deretan file yang kita upload tadi. Sekarang bagian pamungkasnya yaitu download. Buat file dengan nama download.php.

<?php
session_start();
if(isset($_SESSION['uname'])){
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-disposition: attachment; filename='.$_GET['file']);
header('Content-type: '.$_GET['type']);
readfile('uploads/'.$_GET['file']);
}else{

die("Nggak boleh download!");
}
?>

Logikanya juga cukup mudah. Sama seperti pada file index.php, kita menggunakan kondisi dimana jika user sudah masuk dan membuat variable $_SESSION['uname'] maka boleh mendownload jika tidak maka tampilkan text "Nggak boleh download". Bagaimana? Cukup memusingkan bukan? Namanya juga belajar, harus pusing. Nah untuk field id yang 32 char itu adalah tantangan buat Anda bagaimana jika link yang kita buat tidak menggunakan field file_name tetapi id-nya. Jadi lebih aman kan? Jika ada yang ingin ditanyakan silahkan dikomentar. Have a nice coding. :)

3 comments:

Anonymous said...

Masih tetep bisa di download direct acces, walaupun gak login/session gak diregister di server juga.
Kalo contoh seperi itu misal host aplikasi http://fileku.com
file disimpan di folder uplouds dibawah ./root
jadi http://fileku.com/uplouds lalu setelah itu upload file dengan nama flag.png
path nya jadi http://fileku.com/uplouds/flag.png

akses path nya, dapet file nya.

jika memang ingin ada batasan hak akses, content file nya simpan di database(blob) mas.

Best Regards.
Niko Aditya

Teguh Oktian said...

Terima kasih mas Niko untuk sumbangsih sarannya.

Memang kalau kita mengetahui path filenya bisa diakses langsung. Oleh karena itu jika ingin memakai cara ini harus mengganti folder filenya. Misalnya, up10ad, agar tidak mudah diketahui.

Anonymous said...

kalo disimpan di database(blob), jika data sudah banyak akan memakan storage di database dan mengurangi performance pada saat akses ke database

 

Most Reading