I develop a Laravel REST API for an iOS application (being developed by another guy). This means no web-part at all, the application communicates via CURL requests to API. Though cookies are used.
Now I need to check online/offline user status, where socket comes. And I cannot understand how I can authenticate a user on a socket connect.
At all examples I've managed to find a JS script handles authentication at Laravel via PHP sessions and cookies.
So in my scenario for REST API the iOS app gets ACCESS_TOKEN which I can later use in sockets.
A CURL request POSTs login and password and gets access token in JSON format and refresh token in cookie.
curl -kX POST https://site/login -b cookies.txt -c cookies.txt -D headers.txt -H 'Content-Type:application/json' -d '
{
"username":"gruzua",
"password":"qwerty09876",
}'
Response
JSON part
{
"access_token":"ACCESS_TOKEN",
"expires_in":600,
}
Cookie part (just in case):
HTTP/1.1 200 OK
Server: nginx/1.10.3
Content-Type: application/json
Transfer-Encoding: chunked
Connection: keep-alive
Cache-Control: no-cache, private
Date: Wed, 17 May 2017 17:08:09 GMT
Set-Cookie: refreshToken=SOME_REFRESH_TOKEN; expires=Mon, 07-Jan-2019 17:08:09 GMT; Max-Age=51840000; path=/; HttpOnly
On each sequent request CURL sends the ACCESS_TOKEN token to authenticate
curl -kX GET https://site/user -H 'Authorization: Bearer ACCESS_TOKEN'
At this point I have an access token and want to open a socket connection.
According to http://socketo.me/docs/hello-world I can open a telnet connection and write there some JSON formatted data containing my ACCESS_TOKEN. At the server side in a Ratchet ComponentInterface implementation onOpen method I have to check user authorization. Maybe it's not possible onOpen, then the options is onMessage? Anyway
My question is how to use laravel authentication here?
namespace MyApp;
use Ratchet\MessageComponentInterface;
use Ratchet\ConnectionInterface;
class Chat implements MessageComponentInterface {
protected $clients;
public function __construct() {
$this->clients = new \SplObjectStorage;
}
public function onOpen(ConnectionInterface $conn) {
// Store the new connection to send messages to later
/*
Here I have to get somehow the user ACCESS_TOKEN
and to check authorization the way it's checked
when using CURL passes ACCESS_TOKEN in header
Something like this
$user = Auth::user();
if (!emtpy($user))
{
// Check e.g. user permissions (authorization) and allow connection if it's ok
}
else
{
// Reject connection
}
*/
$this->clients->attach($conn);
echo "New connection! ({$conn->resourceId})\n";
}
...
As far as I understand a client can pass a JSON string to socket connection. The server I can query my oauth_access_tokens laravel database for the ACCESS_TOKEN and get my user model and load the corresponding user data. But I think it's not the correct way, as I want to use all the power of Laravel guard/middleware and other coll stuff which I'm not as familiar with as I'd like, but I feel it badly needed. So I want to check authentication not by hands, but to let laravel do the job.
I'm aware of this topic Laravel Ratchet socket Auth , but it speaks of Session and request cookies, which is not possible in my case.