Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Laravel access authenticated user in global scope

I have a multi-user application with the following entity/model relationship.

User belongs to a Company and has many SupportTicket

Users of one company should not have access to the support tickets of other companies - if a user of one company navigates to a url pointing to a support ticket of another company, they should receive a 404 or something equivalent.

I was hoping to define a global scope in the SupportTicket class as follows:

class SupportTicket extends Model {

    protected $fillable = ['company_id'];

    public static function boot() {
        static::addGlobalScope('ofCompany', function(Builder $builder) {
            $authUser = auth()->user();

            $builder->where('company_id', $authUser->company_id);
        });
    }

}

The benefit of a global scope is that it will apply to all queries. Other developers working on the project need not work when retrieving tickets as the right results will always be returned.

For example SupportTicket::all() or SupportTicket::find(5) will always restrict access by user's company.

The challenge I have now is that auth()->user() always returns null as the authenticate middleware has not yet been run.

  1. Is there a way around this?
  2. Has anyone here faced a similar problem and if so how did they go around it?
  3. Is it possible to access the authenticated user in the boot method where the global scope is registered?

Many thanks in advance for any and all responses.

like image 762
biblicalPH Avatar asked Sep 28 '16 17:09

biblicalPH


3 Answers

Laravel 5.6.26 introduced Auth::hasUser() to determine if the current user is already authenticated without querying the User model in your database. You can find more details at https://laravel-news.com/laravel-5-6-26

So you could do something like this:

static::addGlobalScope('ofCompany', function(Builder $builder) {
    if( auth()->hasUser() ){
        $builder->where('company_id', auth()->user()->company_id);
    }     
});
like image 105
maelga Avatar answered Oct 08 '22 17:10

maelga


You can check inside the boot method if there's an authenticated user using \Auth::check() before calling \Auth::user(). If the Auth middleware is wrapping routes or the controller itself then you can access the authenticated user anywhere using the facade \Auth::user()

like image 32
Fabio Ferreira Avatar answered Oct 08 '22 18:10

Fabio Ferreira


If you are using Tymon's JWT Auth package, you can get auth user like this

$authUser = \JWTAuth::parseToken()->authenticate();
like image 20
Sašo Kovačič Avatar answered Oct 08 '22 17:10

Sašo Kovačič