Search code examples
phplaravellaravel-5laravel-passport

Laravel Passport Get Client ID By Access Token


I'm writing a tiny sms gateway to be consumed by a couple of projects,

I implemented laravel passport authentication (client credentials grant token)

Then I've added CheckClientCredentials to api middleware group:

protected $middlewareGroups = [
    'web' => [
       ...
    ],

    'api' => [
        'throttle:60,1',
        'bindings',
        \Laravel\Passport\Http\Middleware\CheckClientCredentials::class
    ],
];

The logic is working fine, now in my controller I need to get client associated with a valid token.

routes.php

Route::post('/sms', function(Request $request) {
    // save the sms along with the client id and send it

    $client_id = ''; // get the client id somehow

    sendSms($request->text, $request->to, $client_id);
});

For obvious security reasons I can never send the client id with the consumer request e.g. $client_id = $request->client_id;.


Solution

  • So, no answers ...

    I was able to resolve the issue by consuming my own API, finally I came up with simpler authentication flow, the client need to send their id & secret with each request, then I consumed my own /oauth/token route with the sent credentials, inspired by Esben Petersen blog post.

    Once the access token is generated, I append it to the headers of Symfony\Request instance which is under processing.

    My final output like this:

    <?php
    
    namespace App\Http\Middleware;
    
    use Request;
    
    use Closure;
    
    class AddAccessTokenHeader
    {
        /**
         * Octipus\ApiConsumer
         * @var ApiConsumer
         */
        private $apiConsumer;
    
    
        function __construct() {
            $this->apiConsumer  = app()->make('apiconsumer');
        }
    
        /**
         * Handle an incoming request.
         *
         * @param  \Illuminate\Http\Request  $request
         * @param  \Closure  $next
         * @return mixed
         */
        public function handle($request, Closure $next)
        {
            $response = $this->apiConsumer->post('/oauth/token', $request->input(), [
                'content-type' => 'application/json'
            ]);
    
    
            if (!$response->isSuccessful()) {
                return response($response->getContent(), 401)
                        ->header('content-type', 'application/json');
            }
    
            $response = json_decode($response->getContent(), true);
    
            $request->headers->add([
                'Authorization'     => 'Bearer ' . $response['access_token'],
                'X-Requested-With'  => 'XMLHttpRequest'
            ]);
    
            return $next($request);
    
        }
    }
    

    I used the above middleware in conjunction with Passport's CheckClientCredentials.

    protected $middlewareGroups = [
        'web' => [
            ...
        ],
    
        'api' => [
            'throttle:60,1',
            'bindings',
            \App\Http\Middleware\AddAccessTokenHeader::class,
            \Laravel\Passport\Http\Middleware\CheckClientCredentials::class
        ],
    ];
    

    This way, I was able to insure that $request->input('client_id') is reliable and can't be faked.