1

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.

AHeavyObject
  • 562
  • 1
  • 7
  • 18

1 Answers1

0

So here is how my solution looks like.

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).

A user connects by telnet and posts a JSON string containing the token. Alas, I didn't manage

telnet 192.168.0.100 8080

{"token":"ACCESS_TOKEN"}

The the ratchet server class looks like this described here Call Laravel controller from code and pass HTTP headers to it

So according to my API controller response (false or current user if autheticated) I can decide if the $conn is authenticated as well.

Here is another narrower question, helping with this question answer: Call Laravel controller from code and pass HTTP headers to it

AHeavyObject
  • 562
  • 1
  • 7
  • 18