19

In api.php routes file below, there are public routes and private routes:

Route::group(['namespace' => 'API'], function() {

     // Public routes (auth not required)
     Route::group([], function() {
         Route::get('/testauth1', 'TestController@testauth1');
         // more public routes...
     });

     // Private routes (auth required)
     Route::group(['middleware' => 'auth:api'], function() {
         Route::get('/testauth2', 'TestController@testauth2');
         // more private routes...
     });

});

In the TestContoller these are the 2 methods called above:

class TestController extends Controller {

    public function testauth1(\Request $request) {
      // return auth()->user(); // does not return user
      return $request->user(); // does not return user
    }

    public function testauth2() {
      return auth()->user(); // returns user
    }

}

Since the private route group has the auth:api middleware, we will ensure the user is authenticated by checking the token supplied in the Authorization Bearer header. Only if a valid token is present will the private routes be rendered to the authenticated user. This is why TestController@testauth2 returns the auth user correctly.

Now, anyone can access the public routes, with or without token. If there is no token supplied in the Authorization Bearer header, then we'll have no authenticated user, which makes sense. This is why TestController@testauth1 does not return an auth user. However, when a logged in user accesses /testauth1 public route, they provide their token in the Authorization Bearer header and therefore should be returned in TestController@testauth1 if not with auth()->user() at least with the $request->user() but we can't seem to access the user with their supplied token in that method.

Any idea how we can access the valid token user in all public route methods?

Wonka
  • 8,244
  • 21
  • 73
  • 121

2 Answers2

48

Pass the api guard as a parameter to fetch the authorized user without the middleware protecting the request.

$request->user('api');

// Or

auth('api')->user();
Aken Roberts
  • 13,012
  • 3
  • 34
  • 40
  • Works correctly, for $request had to implement path suggest by Mark Walet, both work really well. Thank you! – Wonka Jun 06 '18 at 00:10
9

You are referencing Request from a root namespace: \Request. Instead, you should reference the Illuminate\Http\Request class.

You should remove the \ from your parameter and add the following line to your imports.

use Illuminate\Http\Request;

Alternatively, you could also reference the request class directly in your method:

class TestController extends Controller {

    public function testauth1(Illuminate\Http\Request $request) {
        return $request->user();
    }

    public function testauth2() {
        return auth()->user(); // returns user
    }

}

The auth() helper method or Auth Facade is globally available. It doesn't depend on the request that you are trying to access. The same goes for the request() and Request:: helpers I believe. In the case you are giving, you are referencing a wrong Request instance, hence giving a unexpected result.

Mark Walet
  • 1,147
  • 10
  • 21
  • 2
    Your suggested path works really well, the only issue was it was still not returning the auth user. The solution was to do `$request->user('api');` if using request or the alternative `auth('api')->user();` without the request as in Aken Roberts answer. Thank you very much for your answer, upvoted :) – Wonka Jun 06 '18 at 00:12