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', LaravelPassportHttpMiddlewareCheckClientCredentials::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;
.
Advertisement
Answer
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 SymfonyRequest
instance which is under processing.
My final output like this:
<?php namespace AppHttpMiddleware; use Request; use Closure; class AddAccessTokenHeader { /** * OctipusApiConsumer * @var ApiConsumer */ private $apiConsumer; function __construct() { $this->apiConsumer = app()->make('apiconsumer'); } /** * Handle an incoming request. * * @param IlluminateHttpRequest $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', AppHttpMiddlewareAddAccessTokenHeader::class, LaravelPassportHttpMiddlewareCheckClientCredentials::class ], ];
This way, I was able to insure that $request->input('client_id')
is reliable and can’t be faked.