0

I am using Laravel guard to to protect routes, now I want to get user id in unprotected (common) routes, for example:

Protected:

/Profile

Unprotected:

/Search

I able to get user id in protected routes, for example ProfileController.php, like this:

$id = auth()->guard('agent')->user()->id;

But I want to get this in searchController.php but it return null, any idea?

api.php:

Route::middleware('auth:agent')->group(function () {
    Route::get('profile', 'ProfileController@details');
});

Route::post('search', 'searchController@search');

In other hand, when user is logged, and open search page, I want to get user id.

Jack The Baker
  • 1,781
  • 1
  • 20
  • 51
  • 1
    Store `id` in `cookie` can be an `option` *!* – Pedram Feb 15 '20 at 10:27
  • I might sound silly, but when you're accessing `/search` route - are you authenticated at that point via `agent` guard? – Sebastian Sulinski Feb 15 '20 at 13:57
  • @SebastianSulinski no, `search` not using guard – Jack The Baker Feb 15 '20 at 14:04
  • I understand that, but when you're trying to access `/search` - are you logged in at that point or not? If you're not logged in then obviously there will be no user because none has been authenticationd. – Sebastian Sulinski Feb 15 '20 at 14:05
  • @SebastianSulinski Actually, if you logged, or not, you can access Search page, just I need if user is logged, pass it user id into the search result to see a button – Jack The Baker Feb 15 '20 at 14:08
  • I just tried it my end and it seems to work - if you cannot obtain instance of the `User` when you're logged in, then there might be something wrong with your `guard` implementation - probably worth double checking. The only time you should get `null` would be if visitor is not authenticated with the `agent` guard. – Sebastian Sulinski Feb 15 '20 at 14:21
  • @SebastianSulinski I thought if search not under guard middleware group, it can not access to instance of the User, so I was wrong? - I don't know, I think it work without any issue, but the only problem is, I can not access user instance outside of protected route – Jack The Baker Feb 15 '20 at 14:24
  • You are able to access user for any guard on any route in your application as long as that user is authenticated (logged in). I'll post what I tested as the answer so you can see. Middleware like the one you attached to your route usually only checks whether user is authenticated for a given guard, unless that's where you authenticate the user - can you post the contents of the middleware you bound to the protected route? – Sebastian Sulinski Feb 15 '20 at 14:28
  • 1
    No problem - please check the answer - it all works fine. Are you using default `App\Http\Middleware\Authenticate::class` middleware or did you modify it in any way? If the default one than it's most likely the implementation of the guard. – Sebastian Sulinski Feb 15 '20 at 14:37

2 Answers2

2

So continuing from my comments above - here's what I tried and works without any glitch:

config/auth.php

'guards' => [
    //..

    'agent' => [
        'driver' => 'session',
        'provider' => 'users',
    ],

    //...
],

app/Http/Controllers/HomeController.php

public function index(): JsonResponse
{
    return new JsonResponse([
        'user' => auth()->guard('agent')->user(),
    ]);
}

routes/web.php

Route::get('/', 'HomeController@index')->name('home');

tests/Feature/HomeTest.php

/**
 * @test
 */
public function returns_user()
{
    $this->actingAs($user = factory(User::class)->create(), 'agent');

    $this->assertTrue($user->exists);
    $this->assertAuthenticatedAs($user, 'agent');

    $response = $this->get(route('home'));

    $response->assertExactJson([
        'user_id' => $user->toArray()
    ]);
}

/**
 * @test
 */
public function does_not_return_user_for_non_agent_guard()
{
    $this->actingAs($user = factory(User::class)->create(), 'web');

    $this->assertTrue($user->exists);
    $this->assertAuthenticatedAs($user, 'web');

    $response = $this->get(route('home'));

    $response->assertExactJson([
        'user_id' => null
    ]);
}

And the test passes just fine so I can only guess that there's either something with your implementation of the agent guard or the auth:agent middleware.

Sebastian Sulinski
  • 5,815
  • 7
  • 39
  • 61
2

You should create a controller that pass user data such id or etc:

Route::middleware('auth:agent')->group(function () {
    Route::get('userdata', 'ProfileController@userdata'); // return user id
});

And:

public function userdata(){
   ...
   $id = auth()->guard('agent')->user()->id; // just id
   return $id;
}

This controller can fetch all user data, now you should need to call this request in your search controller:

app('App\Http\Controllers\ProfileController')->userdata();
Pedram
  • 15,766
  • 10
  • 44
  • 73