Using jwt-auth in Laravel to let user act on behalf of another user

Using tokens to login on behalf of another user in a Laravel web application. How do you take care of that?

Posted by Eddo on August 7, 2018

There are cases when you have multiple sorts of users in your system, like employees and clients. In some cases you want to employees to login as the clients, without needing their password. You want to ensure though that some items in your application or API stay private for the clients (remember GDPR 😉 ).

You can achieve that by using tokens, which is a very common way already to keep a logged in in a lot of web application, although usually abstracted away by the framework. In this example I’d like to show you how we achieved a solution within a web app that uses an API driven by Laravel.

Note: I’m only providing some small examples here, and not writing a complete application.

From the start you need a function to actually login as the client, in which you set up the authentication token. We’ve selected the jwt-auth library as we’re using Laravel and it suited our needs. The token is created by jwt-auth based on a the client-user in this case. In our Client user model in Laravel, we’ve setup getJWTCustomClaims which is used by jwt-auth in the from-user function.

public function loginAsClient($client_id)
{
    if (! $user = Client::find($client_id)) {
        return Redirect::to("/");
    }

    return redirect('https://client_app_url?' . http_build_query([
            'auth.user_id' => $user->id,
            'auth.token' => JWTAuth::fromUser($user),
        ]);
    );
}

Function to login as a client

You can see that within getJWTCustomClaims() we’re checking the current logged in user based on the Laravel function auth->user(), which might return me being an Employee. If so, we’re setting a few claims that we’re an actor.

/**
 * Return a key value array, containing any custom claims to be added to the JWT.
 *
 * @return array
 */
public function getJWTCustomClaims()
{
    $claims = ['type' => JwtUserType::CLIENT];

    if (auth()->user() instanceof Employee) {
        $claims['actor_type'] = JwtUserType::EMPLOYEE;
        $claims['actor_id'] = auth()->user()->id;
    }

    return $claims;
}

Setting specific claims that we’re acting on behalf of the client as employee

In our API we’ve setup a function that actually checks those claims and acts accordingly.

protected function is_acting_on_behalf_of_user() : bool
{
    return JWTAuth::getToken()
    	&& JWTAuth::parseToken()->getPayload()->getClaims()->has('actor_type', 'actor_id');
}

I’m sharing this as I couldn’t find a lot regarding the use of JWT custom claims on the internet in such a way, and I thought it would be a useful. Not taking credit for coming up with this structure, as that was done by another developer in our team. If you’d like to setup jwt-auth from scratch in a Laravel application, I’d suggest you take a look at Moses Esan’s tutorial. If you have any questions or improvements, please ping me on Twitter.

P.S. If you’ve enjoyed this article or found it helpful, please share it, or check out my other articles. I’m on Instagram and Twitter too if you’d like to follow along on my adventures and other writings.