how to use scramble in production

614 views Asked by At

I'm trying to document my laravel api and I'm using the scramble package. Locally everything works fine but in a production environment there's a bug (a 403 error when I access the page).

I followed the documentation and added a gate(The e-mail I'm showing you is just an example, to be on the safe side.)

Gate::define('viewApiDocs', function (User $user) {
  return in_array($user->email, ['[email protected]']);
});


<?php

namespace Dedoc\Scramble\Http\Middleware;

use Illuminate\Support\Facades\Gate;

class RestrictedDocsAccess
{
    public function handle($request, \Closure $next)
    {
        if (app()->environment('local')) {
            return $next($request);
        }

        if (Gate::allows('viewApiDocs')) {
            return $next($request);
        }

        abort(403);
    }
}


//new middleware
    public function handle($request, \Closure $next)
    {
        $user = $request->session()->get('user');
        if (app()->environment('local')) {
            return $next($request);
        }

        if (!$user) {
            return redirect('login');
        }
        
        if (in_array($user->email, ["[email protected]"])) {
            return $next($request);
        }

        abort(403);
    }

and at the end I'd like to have my documentaion as in a local environment

2

There are 2 answers

6
Denis Sinyukov On BEST ANSWER
  1. php artisan vendor:publish
  2. Select scramble-config
  3. change config/scramble.php file - middleware section: RestrictedDocsAccess::class - override your class

Package middleware

public function handle($request, \Closure $next)
{

    if (app()->environment('local')) {
        return $next($request);
    }

    if (Gate::allows('viewApiDocs')) {
        return $next($request);
    }

    abort(403);
}
<?php

namespace App\Http\Middleware;

class MyRestrictedDocsAccess
{
    public function handle($request, \Closure $next)
    {
        if (app()->environment('local')) {
            return $next($request);
        }

        $user = $request->user();

        if (in_array($user->email, ['[email protected]'])) {
            return $next($request);
        }

        abort(403);
    }
}


config/scramble.php

    'middleware' => [
        'web',
        \App\Http\Middleware\MyRestrictedDocsAccess::class,
    ],
1
Chris Wray On

In their docs, they say to define the viewApiDocs Gate to access the docs in production but don't say how to define the Gate.

So how do you define the viewApiDocs Gate?

To define a viewApiDocs Gate, the process is pretty simple. First, you need to go to your AuthServiceProvider and find your boot() method. In this method, you will define the Gate as follows:

   /**
     * Register any authentication/authorization services.
     *
     * @return void
     */
    public function boot()
    {
        //

        Gate::define('viewApiDocs', function (User $user) {
            return in_array($user->email, ['[email protected]']);
        });
    }

Inside your Gate definition, you can do whatever you would like. If you want everyone to be able to access your API documentation, you can return true.

In the example you shared, you tried to implement the viewApiDocs Gate, but you were doing this outside of the AuthServiceProvider boot() method. In order to make your gate properly work, you must define it inside the AuthServiceProvider boot method.

If you define your Gate properly, you do NOT need to override the RestrictedDocAccess class.