How would I do a middleware to catch the user if there is a token and if it does not have a token, to continue without blocking the request?

Published 4 months ago by valdinei.lima

Hello everyone, I have a "domain.com/v1/campaigns" route that returns a list of data. This route does not need to have a token to access. But if there is a token entered in the header, I'd like to return the user's data. I can not use the "auth: api" middleware because it would make the route always require a token, and that would not be the case. The token on this route would be optional. How would I do a middleware to catch the user if there is a token and if it does not have a token, to continue without blocking the request?

Imagine the situation... I have this route:

ROUTE

$router->get('campaign/{slug?}', [
    'uses' => '[email protected]'
]);

This route is public, ie it is not necessary to inform a token in order to list the items. However, if the user is connected, every time he accesses the route, a token is added to the header (Bearer XYZZYZXZ...)

In the controller, I need to get the user's model if there is a token informed, but I can not.

CONTROLLER

class ControllerPublic extends ApiController
{
    public function getCampaign($slug)
    {

        // THERE IS NO TOKEN IN THE HEADER PRINT USER //
        if (auth()->check()) {
            dd(auth()->user()->toArray());
        }

        $data = $this->call(GetCampaignPublicAction::class, [$slug]);
        return $this->transform($data, CampaignTransformer::class);
    }
}
Best Answer (As Selected By valdinei.lima)
martinbean

@valdinei.lima Can you not get the user in the controller action if there is one, and then display their points that way?

class CampaignController extends Controller
{
    public function show(Campaign $campaign)
    {
        $user = auth('api')->user();

        $points = $user ? $user->points : 0;
    }
}

This doesn’t feel like a middleware problem because you’re not manipulating a HTTP request or response. You’re just wanting to do something if there’s a user or not, which is logic and better belongs in a controller.

thinsoldier

If there is a token in the "header"... (do you mean the url?) ... you want to show the user's data. What will be shown if there is no user token?

If the user is connected, every time he accesses the route, a token is added to the "header".

I am not sure exactly what you mean by header the 2 times you said header.

Are you saying: If the user is logged in, show them their own private data when they visit /campaign/ but if they are not logged in, show all of the public items?

valdinei.lima

Are you saying: If the user is logged in, show them their own private data when they visit /campaign/ but if they are not logged in, show all of the public items?

The frontend is a SPA in VUE.

The route 'campaign/{slug?}' is public, it can be accessed without a token. However, the SPA can sometimes send token in the header. If there is a token I would like to check return the user.

thinsoldier

Oh. Sorry. I'm not that advanced yet. :( Can't help. Sorry.

Can tokens only be detected by middleware? It sounds like you need a simple if/else based on whether or not there is a token. Is there an easier place to put that other than inside of middleware? Can you make your own middleware?

ejdelmonico

MIddleware is simply a layer that looks for something specific (your requirements) and then passes off to the next middleware. You can effectively use middleware to allow a policy or a role or both to a user. Read over authentication in the docs.

valdinei.lima

Let's forget a previous question. Now, how would I return a User, just knowing the token. How do I ask for Laravel Passport which is the user only informing the a string token?

martinbean

@valdinei.lima I’m still struggling to understand what you’re trying to achieve.

You have a route that is publicly-accessible. What is it you want to do in the controller if there is a token passed?

valdinei.lima

@martinbean My campaign route returns a attribute "total_points = 0". But if a user who found this route sent a token, then I need to get the user data to return the points of it.

For me to use "auth()->user()" inside controller, I have to go through an "auth: api" middleware, in this case a no longer public route because it would always require a token.

So, I have not added the "auth()->user()" middleware so that you are more public, but I am not welcome to the user on the route.

martinbean

@valdinei.lima Can you not get the user in the controller action if there is one, and then display their points that way?

class CampaignController extends Controller
{
    public function show(Campaign $campaign)
    {
        $user = auth('api')->user();

        $points = $user ? $user->points : 0;
    }
}

This doesn’t feel like a middleware problem because you’re not manipulating a HTTP request or response. You’re just wanting to do something if there’s a user or not, which is logic and better belongs in a controller.

valdinei.lima

@martinbean I was calling "$user = auth()->user();" without specifying the guard. Now it worked by passing this way "$user = auth('api')->user();"

thank you so much!

martinbean

@valdinei.lima No problem. Glad you sorted it :)

Please sign in or create an account to participate in this conversation.