drs
drs

Reputation: 1255

Laravel Vapor- Allow unauthenticated user perform an upload

By default Laravel Vapor requires the user be authenticated to perform an upload. I need to allow an unauthenticated perform an upload. How can I do this?

Thanks

Upvotes: 0

Views: 726

Answers (3)

audiojames
audiojames

Reputation: 122

Perhaps a cleaner way than overriding the route and controller would be to allow guests through the authorization gate.

According to the docs, we can allow guests to pass the gate by making the user argument optional or defaulting to null. https://laravel.com/docs/10.x/authorization#guest-users

Since the default controller method does not explicitly specify the User model, the UserPolicy will not be called for guests. We can overcome this by defining an uploadFiles gate in the boot method of your AuthServiceProvider:

Gate::define('uploadFiles', function (?User $user, $bucket) {
        // Your Auth Here
    });

Upvotes: 1

ceejayoz
ceejayoz

Reputation: 180004

We handled this by overriding the default vapor/signed-storage-url route's handling.

In routes/web.php.

Route::post('vapor/signed-storage-url', [Controllers\SignedStorageUrlController::class, 'store']);

In our SignedStorageUrlController, we use the store function with this check removed:

Gate::authorize('uploadFiles', [
    $request->user(),
    $bucket = $request->input('bucket') ?: $_ENV['AWS_BUCKET'],
]);

resulting in:

<?php

namespace App\Http\Controllers;

use Illuminate\Support\Str;
use Illuminate\Http\Request;
use Laravel\Vapor\Http\Controllers\SignedStorageUrlController as VaporSignedStorageUrlController;

class SignedStorageUrlController extends VaporSignedStorageUrlController
{
    public function store(Request $request)
    {
        $this->ensureEnvironmentVariablesAreAvailable($request);

        $bucket = $request->input('bucket') ?: $_ENV['AWS_BUCKET'];

        $client = $this->storageClient();

        $uuid = (string) Str::uuid();

        $signedRequest = $client->createPresignedRequest(
            $this->createCommand($request, $client, $bucket, $key = ('tmp/'.$uuid)),
            '+5 minutes'
        );

        $uri = $signedRequest->getUri();

        return response()->json([
            'uuid' => $uuid,
            'bucket' => $bucket,
            'key' => $key,
            'url' => 'https://'.$uri->getHost().$uri->getPath().'?'.$uri->getQuery(),
            'headers' => $this->headers($request, $signedRequest),
        ], 201);
    }
}

Upvotes: 0

iosifv
iosifv

Reputation: 1219

I think if you add something like this in your UserPolicy, vapor should work

public function before($user)
{
    if (Auth::guest()) {
        return true;
    }
}

Upvotes: 0

Related Questions