Here is my solution (Laravel 5.4). Inspired by https://stackoverflow.com/a/40366119/518704 but needed much time to dig into the code to find how to pass my Authorization: Bearer token
I need this approach to authorize in a browser-less socket connection (Ratchet), where JS code is not running. So I could not use Ratchet WebSocket, only simple socket Ratchet IoServer. My API controller returns JSON so it's easy to work with the response further. I need this approach mainly to authenticate the socket connection assuming the client knows the access token when one opens the socket (got by REST on login).
First of all I need to use a trait, used in Tests
Next in onMessage code I assume a JSON message is passed with the access token. To simplify here I don't write JSON validity check etc.
namespace App;
use Ratchet\ConnectionInterface;
use Askedio\LaravelRatchet\RatchetServer as RatchetServerBase;
class RatchetServer extends RatchetServerBase
{
...
public function onMessage(ConnectionInterface $conn, $input)
{
$input = json_decode($input);
$token = $input->token;
// Some data (may be taken from JSON $input)
$data = [
"param1" => "value 1",
"param2" => "value 2",
"param3" => "value 3"
];
// Prepare the server headers
$server = ['HTTP_AUTHORIZATION' => 'Bearer ' . $token];
// This way! If calling app() here, it reuses the same Auth::user()
$app = require __DIR__.'/../bootstrap/app.php';
$kernel = $app->make(\Illuminate\Contracts\Http\Kernel::class);
$response = $kernel->handle(
$request = \Illuminate\Http\Request::create('/user', 'GET', $data, [], [], $server)
);
// ~ var_dump(Auth::id());
$controllerResult = $response->getContent();
$kernel->terminate($request, $response);
// My controller hidden under /user route is an API one and returns JSON string
echo $controllerResult;
}
...
}
My previous solution didn't work. The Auth::user() always returned the
first logged in user (app() seemed to use singleton). So I leave the
previous code for reference purpose.
namespace App;
use Ratchet\ConnectionInterface;
use Askedio\LaravelRatchet\RatchetServer as RatchetServerBase;
class RatchetServer extends RatchetServerBase
{
use \Illuminate\Foundation\Testing\Concerns\MakesHttpRequests;
...
public function onMessage(ConnectionInterface $conn, $input)
{
$input = json_decode($input);
$token = $input->token;
$data = [
"param1" => "value 1",
"param2" => "value 2",
"param3" => "value 3"
];
// The 2 lines below can me moved to the __constructor method
$this->baseUrl = request()->getSchemeAndHttpHost();
$this->app = app();
// Prepare the server headers
$server = ['HTTP_AUTHORIZATION' => 'Bearer ' . $token];
// Call my controller by route (this seems to be internal call)
$response = $this->call('GET','/method', $data, [], [], $server)->json();
}
...
}
P.S. Just a note for myself when I come here later. Too see available headers and proper naming I did a var_dump in for $this->parameters
./vendor/symfony/http-foundation//ServerBag.php