Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Authorization only works if user authenticated with 'web' guard #294

Closed
shahvirag opened this issue Nov 1, 2018 · 15 comments
Closed

Authorization only works if user authenticated with 'web' guard #294

shahvirag opened this issue Nov 1, 2018 · 15 comments

Comments

@shahvirag
Copy link

shahvirag commented Nov 1, 2018

I am using multiple guard in my application.

code1

For production use of Telescope, If i allow any user belongs to web guards so it works fine. But if I logged in with 'admin' guard than user not authenticated for telescope access. I have already defined user emails in service provider gate method.

Originally posted by @shahvirag07 in https://github.com/laravel/telescope/issue_comments#issuecomment-434941088

@paras-malhotra
Copy link
Contributor

Don't think this has to do with the package. Can you post your authorization and gate functions in your TelescopeServiceProvider?

@shahvirag
Copy link
Author

shahvirag commented Nov 1, 2018

Here is my gate function.

code1

virag@myapp.com which uses 'web' guard and dev@myapp.com uses 'admin' guard.
If I logged in with virag@myapp.com it works perfectly. But I only want to configure for user who can logged in with 'admin' guard.

@paras-malhotra
Copy link
Contributor

paras-malhotra commented Nov 1, 2018

This has nothing to do with Telescope. You're always free to override the authorization function in your TelescopeServiceProvider. I suspect the issue is your implementation of multiple guards. Make sure you're using the latest Authenticate middleware and if not, you must call the shouldUse on your authentication factory to switch out the default guard.

@themsaid
Copy link
Member

themsaid commented Nov 1, 2018

Telescope uses $request()->user() to get the user, if you don't have a default guard this won't work, you can however use Telescope::auth() to override this behaviour.

Telescope::auth(function ($request) {
    return app()->environment('local') ||
           Gate::check('viewTelescope', [$request->user('YOUR_GUARD_HERE')]);
});

@admench
Copy link

admench commented Nov 17, 2018

I am struggling to get this working, sorry to bother you!

In my App\Providers\TelescopeServiceProvider:

protected function authorization()
    {
        $this->gate();

        Telescope::auth(function ($request) {
            return app()->environment('local') ||
                $request->user('web')->can('viewTelescope');
        });
    }

protected function gate()
    {
        Gate::define('viewTelescope', function ($user) {
            return \in_array($user->email, [
                'me@gmail.com',
            ], true);
        });
    }

In the authorization method, if I dd($request->user('web')->can('viewTelescope')) within the function, I can toggle between true and false when altering the specified email in the in_array check within the gate method. However, even when disabling the first line that checks for local environment, I can always see telescope. What am I doing wrong? Thanks

@kiwina
Copy link

kiwina commented Dec 5, 2018

I had the same issue, the gate resolves the user with the default guard even when passing
$request->user('admin') for example.
but if i add in authorization
auth()->setDefaultDriver('admin');
then it works fine

@jezzdk
Copy link

jezzdk commented Dec 13, 2018

@kiwina Your solution worked for me. Thanks!

Edit: I was wrong. It killed the authentication on non-default guards.

@drsdre
Copy link

drsdre commented Jun 7, 2019

@kiwina I can confirm that changing guard using the following code in TelescopeServiceProvider works:

/**
 * Configure the Telescope authorization services.
 *
 * @return void
 */
protected function authorization()
{
	Auth::setDefaultDriver('admin');
	parent::authorization();
}

@WizardPro
Copy link

WizardPro commented Jan 3, 2020

in my case , the auth()->setDefaultDriver('admin') method broken my api authorization.
i found Gate::forUser function, that worked for me and everything looked corrected.

protected function authorization()
{
    $this->gate();
    Telescope::auth(function ($request) {
        return app()->environment('local') ||
            Gate::forUser(Admin::user())->check('viewTelescope', [$request->user('admin')]);
    });
}

protected function gate()
{
    Gate::define('viewTelescope', function ($user) {
        return $user->inRoles(['administrator']);
    });
}

ps: the Admin::user() function is in laravel-admin package

@matthillman
Copy link

Yet another solution for the authenticate override… I just looped over all the defined guards and checked each one individually instead of locking telescope down to one specific guard:

protected function authorization()
    {
        $this->gate();

        Telescope::auth(function ($request) {
            $result = collect(config('auth.guards'))->keys()->reduce(function($auth, $guard) use ($request) {
                if ($auth) {
                    return $auth;
                }

                app('auth')->shouldUse($guard);

                return Gate::check('viewTelescope', [$request->user()]);
            }, app()->environment('local'));

            app('auth')->shouldUse(config('auth.defaults.guard'));

            return $result;
        });
    }

@bernhardh
Copy link

Why not just

    protected function gate()
    {
        Gate::define('viewTelescope', function() {
            return auth("admin")->user()->isAdmin();
        });
    }

where isAdmin() has to be replaced by your logic?

@hellomustaq
Copy link

hellomustaq commented Jul 4, 2022

Yet another solution for the authenticate override… I just looped over all the defined guards and checked each one individually instead of locking telescope down to one specific guard:

protected function authorization()
    {
        $this->gate();

        Telescope::auth(function ($request) {
            $result = collect(config('auth.guards'))->keys()->reduce(function($auth, $guard) use ($request) {
                if ($auth) {
                    return $auth;
                }

                app('auth')->shouldUse($guard);

                return Gate::check('viewTelescope', [$request->user()]);
            }, app()->environment('local'));

            app('auth')->shouldUse(config('auth.defaults.guard'));

            return $result;
        });
    }

With multiple guards, this solution worked for me. Thanks @matthillman

@kresnasatya
Copy link

Here's what I do in my code.

protected function authorization()
    {
        // Always set `Auth::shouldUse('YOUR_GUARD')` before calling Gate methods like allow, denies, define, check, etc.
        // Link: https://github.com/laravel/framework/issues/13788#issuecomment-249550532
        Auth::shouldUse('YOUR_GUARD');
        
        $this->gate();
        
        Telescope::auth(function ($request) {
            return Gate::check('viewTelescope', [$request->user('YOUR_GUARD')]);
        });
    }

    /**
     * Register the Telescope gate.
     *
     * This gate determines who can access Telescope in non-local environments.
     *
     * @return void
     */
    protected function gate()
    {
        Gate::define('viewTelescope', function ($user) {
            // Just in case if you want to make sure if there's a user. Store that data in laravel.log to check later.
            Log::info($user);
            return in_array($user->email, [
                'yourmail@mail.com'
            ]);
        });
    }

Hope it helps for everyone include my self!

@atrialabir
Copy link

all my guards are api base and I use passport. after overwrite authorization method, how can I set a valid berear token to access telescope panel?

``

/**
 * Configure the Telescope authorization services.
 *
 * @return void
 */
protected function authorization()
{
    $this->gate();

    Telescope::auth(function ($request) {
        return Gate::check('viewTelescope', [$request->user('admin:api')]);
    });
}

@akiftezcan38
Copy link

It's work for me. Thanks bro

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests