Cara Upload File Di Laravel Ke Storage Public Dengan Aman

Cara Upload File Di Laravel Ke Storage Public Dengan Aman
Konten Halaman

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 images
  • return back()->with('success', 'Berhasil melakukan upload file di laravel') ->with('image', $imageName); : method with 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 buat
  • Route::get('image-upload' : penggalan kode ini kita definisikan atau mengarahkan ke endpoint URL image-upload maka misal jika dijalankan di local menjadi http://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 opsional
  • Route::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.