Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

musciplay's avatar

auth()->user() is pulling in wrong user models in a queued action.

I have a strange bug I am a bit stumped on.

TLDR: auth()->user() is sometimes returning a user model instance while in the queue. My log "updater" is being assigned to a random, unrelated user.

Some more details

  1. this "log" model is called within various synchronous & queued actions (jobs). "HasLogs" is a trait on multiple models.
$order->log('log_key', 'log_message');

And the method (is a trait on the "Order" model)

   public function log($key, $log, Model $updater = null): void
   {
      if (is_null($updater) && auth()->user()) $updater = auth()->user();
      if (is_null($updater) && !auth()->user()) $updater = Custodian::find(Custodian::NAMES['System']);

      $this->changelog()->create([
         'log_key'      => $key,
         'log_value'    => $log,
         'updater_id'   => $updater?->id,
         'updater_type' => (! is_null($updater)) ? get_class($updater) : NULL,
      ]);

The purpose of the auth()->user() call is for synchronous actions to pull in the currently logged in user as the updater automatically.

For the queued actions however, I am not intending auth()->user() to be used while in the queue, but am actually hoping it returns "null" and instead say the log was updated by the "System". Ex. responding to a webhook from Stripe, or sending an email (w. "ShouldQueue" included).

What is happening however is sometimes a random user is being assigned as the "updater" on asynchronous action. They are not related in any way to the action, and it's not like "Order # 350" -> assigning to user # 350.

I can't confirm 100%, but it does appears to be a user who previously was assigned the "$updater" of another log.

  • No "$updater" is being passed in queued log actions.
  • It's not a bulk-update, as the log "Created_at" and "updated_at" time match exactly
  • It's not just a one-off either, I've seen the same user be assigned to many (30+) logs.

Any ideas?

0 likes
4 replies
LaryAI's avatar
Level 58

It sounds like the issue you're encountering is due to the fact that the queued jobs are sometimes retaining the authentication state from the time they were queued, which can lead to unexpected behavior when auth()->user() is called within the job.

To ensure that auth()->user() returns null in queued jobs, you can explicitly set the user to null at the beginning of the job. This will prevent any residual authentication state from affecting your logs.

Here's a possible solution:

  1. Clear the authentication state at the beginning of the job:

    Modify your job class to clear the authentication state before performing any actions. This can be done by setting the authenticated user to null.

    use Illuminate\Support\Facades\Auth;
    
    class YourJobClass implements ShouldQueue
    {
        public function handle()
        {
            // Clear the authentication state
            Auth::setUser(null);
    
            // Your job logic here
            $order->log('log_key', 'log_message');
        }
    }
    
  2. Ensure the log method handles the null user correctly:

    Your log method already handles the case where auth()->user() is null by assigning the Custodian::find(Custodian::NAMES['System']) user. This part of your code seems correct, so no changes are needed here.

    public function log($key, $log, Model $updater = null): void
    {
        if (is_null($updater) && auth()->user()) {
            $updater = auth()->user();
        }
        if (is_null($updater) && !auth()->user()) {
            $updater = Custodian::find(Custodian::NAMES['System']);
        }
    
        $this->changelog()->create([
            'log_key'      => $key,
            'log_value'    => $log,
            'updater_id'   => $updater?->id,
            'updater_type' => (!is_null($updater)) ? get_class($updater) : NULL,
        ]);
    }
    

By explicitly setting the authenticated user to null at the beginning of your queued job, you can ensure that auth()->user() will return null and your log method will correctly assign the "System" user as the updater.

This should resolve the issue of random users being assigned as the updater in your logs.

1 like
tisuchi's avatar

@musciplay Can you please ensure auth()->user() is null when expected, explicitly passing the updater where needed, and verifying that no middleware or provider is improperly managing the authentication state?

1 like
Snapey's avatar

push the user into the job. Dont rely on auth()->user() being available in ANY job

2 likes
musciplay's avatar

Thanks for the help! I have had some success in cleaning up the error, just was curios if there was any low-level queue behaviour / session issues I didn't know about

Please or to participate in this conversation.