Cara Upload File Di Laravel Ke Storage Public Dengan Aman
Berikut ini proses cara laravel file upload ke folder public atau storage laravel dan menyimpan path folder di database untuk tujuan nya menampilkan gambar dari database di laravel dan melakukan aksi delete, update, dan simpan di folder project laravel.
Install laravel di localhost
Di tutorial cara upload file ke laravel, folder project disini menggunakan laravel 8.x dangan php versi 7.4 langsung saja kita jalankan composer install seperti berikut ini :
composer create-project laravel/laravel:^8.0 upload-file
bagi yang masih belum paham mengenai intallasi laravel bisa baca post berikut Cara Install Laravel di Windows atau Cara install PHP di Windows dan Berjalan di CMD (Command Prompt)
Membuat Controller untuk upload file
Setelah melakukan instalasi laravel maka lanjut kita membuat sebuat controller laravel di app/Http/Controllers/ImageUploadController.php
controller ini akan melakukan proses penyimpanan file dari proses upload file yang terjadi di blade HTML form bertipe upload, berikut ini codingannya :
// app/Http/Controllers/ImageUploadController.php
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class ImageUploadController extends Controller
{
public function imageUpload()
{
return view('imageUpload');
}
public function imageUploadPost(Request $request)
{
$request->validate([
'image' => 'required|image|mimes:jpeg,png,jpg,gif,svg|max:1024',
]);
$imageName = time().'.'.$request->image->getClientOriginalExtension();
$request->image->move(public_path('images'), $imageName);
return back()
->with('success', 'Berhasil melakukan upload file di laravel')
->with('image', $imageName);
}
}
Penjelasan :
return view('imageUpload');
: mengembalikan view blade di controller$request->validate([
: melakukan validasi data yang dikirim ke controller, biasanya melakukan pengecekan tipe data atau ukuran size data$imageName = time().'.'.$request->image->getClientOriginalExtension();
: disini melakukan generate name dengan mengambil nama dan ekstensi file yang dikirimkan oleh sisi client.$request->image->move(public_path('images'), $imageName);
: di kode ini melakukan proses di method move yang artinya memindahkan dari data image ke folder public bagian folder imagesreturn back()->with('success', 'Berhasil melakukan upload file di laravel') ->with('image', $imageName);
: methodwith
di laravel untuk melakukan set session sementara biasanya berisi data temporary yang diisi untuk notif, parameter pertama key array dan parameter kedua berupa data yang akan disimpan
Membuat route di laravel
Setelah membuat controller di laravel untuk keperluan menerima request upload file, kita lanjut untuk membuat routing atau route URL di laravel. Tujuan nya agar bisa diakses via URL web maka bisa diartikan route di laravel ini untuk menjembatani controller dengan client berupa HTTP method GET
atau POST
. Mari kita buat route di folder file routes\web.php
, berikut ini kode untuk melanjutkan controller di laravel yang kita buat sebelumnya :
<?php
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\ImageUploadController;
Route::get('image-upload', [ ImageUploadController::class, 'imageUpload' ])->name('image.upload');
Route::post('image-upload', [ ImageUploadController::class, 'imageUploadPost' ])->name('image.upload.post');
Penjelasan :
use App\Http\Controllers\ImageUploadController;
: dibagian ini tujuannya untuk memanggil contoller yang kita buatRoute::get('image-upload'
: penggalan kode ini kita definisikan atau mengarahkan ke endpoint URLimage-upload
maka misal jika dijalankan di local menjadihttp://localhost/image-upload
, dan memiliki HTTP method GET.[ ImageUploadController::class, 'imageUpload' ]
: bagian ini mengarahkan route URL lanjut untuk pointing ke sebuah method class])->name('image.upload');
: ini penamaan route dan opsionalRoute::post('image-upload',
: ini memiliki HTTP method POST.
Membuat view blade HTML form upload
<!DOCTYPE html>
<html>
<head>
<title>laravel 8 image upload vulnerability - Hosein Vita</title>
<link
rel="stylesheet"
href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css"
/>
</head>
<body>
<div class="container">
<div class="panel panel-primary">
<div class="panel-heading"><h2>Laravel 8 File upload</h2></div>
<div class="panel-body">
@if ($message = Session::get('success'))
<div class="alert alert-success alert-block">
<button type="button" class="close" data-dismiss="alert">×</button>
<strong>{{ $message }}</strong>
</div>
<img src="images/{{ Session::get('image') }}" />
@endif @if (count($errors) > 0)
<div class="alert alert-danger">
<strong>Whoops!</strong>, Ada masalah ketika melakukan input data ke
controller.
<ul>
@foreach ($errors->all() as $error)
<li>{{ $error }}</li>
@endforeach
</ul>
</div>
@endif
<form
action="{{ route('image.upload.post') }}"
method="POST"
enctype="multipart/form-data"
>
@csrf
<div class="row">
<div class="col-md-6">
<input type="file" name="image" class="form-control" />
</div>
<div class="col-md-6">
<button type="submit" class="btn btn-success">Upload</button>
</div>
</div>
</form>
</div>
</div>
</div>
</body>
</html>
Menjalankan Project laravel di localhost
menjalankan command artisan laravel serve :
php artisan serve
Review code mengamankan dari vulnerability upload file di laravel
dari penggalan kode berikut harus diubah karena proses ini langsung menerima extensi file tanpa membaca signature file atau header bentuk file type mime nya.
$imageName = time().'.'.$request->image->getClientOriginalExtension();
maka ubah kode sebelumnya menjadi seperti berikut :
$imageName = time().’.’.$request->image->extension();
penggalan kode diatas mengambil bentuk extensi dari signature bentuk type mime, sehingga jika file di manipulasi untuk mengelabui mime tetapi ekstensi tetap di simpan dari signature file bukan dari nama file langsung.