0

Im saving a request to my database from my vue js via;

public function store(Request $request)
{
  //validate
  $this->validate($request, [
     'name' => 'required',
     'description' => 'required',
     'price' => 'required'
    ]);

    //get image
    $exploded = explode(',', $request->cover_image);
    $decoded = base64_decode($exploded[1]);
    if(str_contains($exploded[0],'jpeg'))
      $extension = 'jpg';
    else
      $extension = 'png';
    $fileName = str_random().'.'.$extension;
    $path = public_path().'/cover_images/'.$fileName;
    file_put_contents($path, $decoded);

    //save
    $product = new Product;
    $product->name = $request->input('name');
    $product->description = $request->input('description');
    $product->price = $request->input('price');
    $product->cover_image = $fileName;
    if($product->save()) {
            return new ProductsResource($product);
    }
}

How can I validate the base64 image? Is my procedure in saving the image coming from vue js is in correct way or is there a better way? please let me know. Thanks im just new to laravel and vue js hoping to learn more

Beginner
  • 1,700
  • 4
  • 22
  • 42

2 Answers2

5

You should add this function to your custom helper :

if (!function_exists('validate_base64')) {

/**
 * Validate a base64 content.
 *
 * @param string $base64data
 * @param array $allowedMime example ['png', 'jpg', 'jpeg']
 * @return bool
 */
function validate_base64($base64data, array $allowedMime)
{
    // strip out data uri scheme information (see RFC 2397)
    if (strpos($base64data, ';base64') !== false) {
        list(, $base64data) = explode(';', $base64data);
        list(, $base64data) = explode(',', $base64data);
    }

    // strict mode filters for non-base64 alphabet characters
    if (base64_decode($base64data, true) === false) {
        return false;
    }

    // decoding and then reeconding should not change the data
    if (base64_encode(base64_decode($base64data)) !== $base64data) {
        return false;
    }

    $binaryData = base64_decode($base64data);

    // temporarily store the decoded data on the filesystem to be able to pass it to the fileAdder
    $tmpFile = tempnam(sys_get_temp_dir(), 'medialibrary');
    file_put_contents($tmpFile, $binaryData);

    // guard Against Invalid MimeType
    $allowedMime = array_flatten($allowedMime);

    // no allowedMimeTypes, then any type would be ok
    if (empty($allowedMime)) {
        return true;
    }

    // Check the MimeTypes
    $validation = Illuminate\Support\Facades\Validator::make(
        ['file' => new Illuminate\Http\File($tmpFile)],
        ['file' => 'mimes:' . implode(',', $allowedMime)]
    );

        return !$validation->fails();
    }
}

Then extend the base64_image validation in your AppServiceProvider in boot() method :

use Illuminate\Support\Facades\Validator;

class AppServiceProvider extends ServiceProvider
{
    /**
     * Bootstrap services.
     *
     * @return void
     */
    public function boot()
    {
        ...

        Validator::extend('base64_image', function ($attribute, $value, $parameters, $validator) {
            return validate_base64($value, ['png', 'jpg', 'jpeg', 'gif']);
        });
    }

Now you can use it in your validation rules like this :

/**
 * Get the validation rules that apply to the request.
 *
 * @return array
 */
public function rules()
{
    return [
        'photo' => 'required|base64_image'
    ];
}
Ahmed Fathy
  • 67
  • 1
  • 2
0

There is a crazybooot/base64-validation package that handles base64 validation.

For installation instructions and more details see: https://github.com/crazybooot/base64-validation

miken32
  • 42,008
  • 16
  • 111
  • 154
Borouch
  • 103
  • 4