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.

tour travel
  • 1,266
  • 1
  • 6
  • 28
  • 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 – tour travel 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 – tour travel 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 – tour travel 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

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
  • 12,941
  • 7
  • 35
  • 64
  • Hmm.. let me try this. just a question, can get this in front too? front of search page – tour travel Feb 16 '20 at 07:40
  • What are you trying to do exactly with user `id`? – Pedram Feb 16 '20 at 07:40
  • just I need if user is logged, pass it user id into the search result to see a button – tour travel Feb 16 '20 at 07:41
  • So why you want to do this in search request, if you are using token, just pass token to get user details, such id and etc, then check it everywhere, such search page and show your target button – Pedram Feb 16 '20 at 07:42
1

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
  • 4,857
  • 5
  • 35
  • 47