centrifugal / centrifuge-js

JavaScript client SDK to communicate with Centrifugo and Centrifuge-based server from browser, NodeJS and React Native. Supports WebSocket, HTTP-streaming over Fetch and Readable Stream API, EventSource, WebTransport.
https://centrifugal.dev
MIT License
411 stars 104 forks source link

Issue with subscribing to a private channel (no problem when subscribing without a token) #267

Closed shimprog closed 10 months ago

shimprog commented 10 months ago

Issue with subscribing to a private channel (no problem when subscribing without a token)

Laravel "denis660/laravel-centrifugo": "^3.1",

React "centrifuge": "^5.0.1",

Centrifugo v5.2.0

In Laravel, I generate the token as follows: $apiSign = $this->centrifugo->generatePrivateChannelToken($user->id, $request->channel['channel'], time() + 5 * 60);

In React, I'm trying to connect as follows:

const centrifuge = new Centrifuge(wss, {
        token: token
    });
    centrifuge.on('connecting', function (ctx) {
        console.log(`connecting: ${ctx.code}, ${ctx.reason}`);
    }).on('connected', function (ctx) {
        console.log(`connected over ${ctx.transport}`);
    }).on('disconnected', function (ctx) {
        console.log(`disconnected: ${ctx.code}, ${ctx.reason}`);
    }).connect();
    return centrifuge

export const getSubscriptionToken = async (channel) => {
    const response = await fetch(`/api/admin/subscription-token`, {
        method: 'POST',
        headers: new Headers({'Content-Type': 'application/json'}),
        body: JSON.stringify({channel: channel})
    });
    const data = await response.json();
    return data.token;
}
const channel = 'personal:1'

const sub = centrifuge.newSubscription(channel, {
                        token: centrifugeInfo.token,
                        getToken: getSubscriptionToken
                    });
                    sub.subscribe();
                    sub.on('publication', handlerPub)

I get the error: error: {code: 103, message: "permission denied"} Server logs: {"level":"info","client":"eef4a6e1-4d25-4ac8-a6fa-ac31d404ff10","code":103,"command":"id:2 subscribe:{channel:\"personal:1\" token:\"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxIiwiaW5mbyI6eyJuYW1lIjoxfX0.jaA1q2uBcrHKXIahveGPDC_yloUrUtFVKzIkJPsrb_o\"}","error":"permission denied","reply":"id:2 error:{code:103 message:\"permission denied\"}","user":"1","time":"2024-01-10T19:04:14+03:00","message":"client command error"}

I tried not adding token: centrifugeInfo.token, since there is already a connection, and as I saw in the documentation, getToken should be sufficient, but then I get: disconnected: 3500, invalid token {"level":"info","channel":"personal:1","client":"29e16073-be7e-4873-8149-627d0e13cbbf","tokenUser":"","user":"1","time":"2024-01-10T19:13:12+03:00","message":"token user mismatch"}

FZambia commented 10 months ago

Hello, it seems that denis660/laravel-centrifugo is not updated to support latest Centrifugo. generatePrivateChannelToken function uses format from Centrifugo v3. I think this may be the reason here.

See this issue btw - https://github.com/denis660/laravel-centrifugo/issues/13

While Laravel package is not updated - you can generate subscription tokens as described in Centrifugo docs - https://centrifugal.dev/docs/server/channel_token_auth, or use function from phpcent https://github.com/centrifugal/phpcent/blob/59717fac8659b7144993e419d5929f2109a26052/src/Client.php#L345

I am not sure – probably there are other things to be updated in Laravel package. I talked to @denis660 recently and he planned to update package - but not sure when exactly it will happen.

If you won't be able to use subscription token generated as described in Centrifugo v5 docs – maybe ask for the help in our communities - https://centrifugal.dev/docs/getting-started/community.

shimprog commented 10 months ago

Hello, it seems that denis660/laravel-centrifugo is not updated to support latest Centrifugo. generatePrivateChannelToken function uses format from Centrifugo v3. I think this may be the reason here.

See this issue btw - denis660/laravel-centrifugo#13

While Laravel package is not updated - you can generate subscription tokens as described in Centrifugo docs - https://centrifugal.dev/docs/server/channel_token_auth, or use function from phpcent https://github.com/centrifugal/phpcent/blob/59717fac8659b7144993e419d5929f2109a26052/src/Client.php#L345

I am not sure – probably there are other things to be updated in Laravel package. I talked to @denis660 recently and he planned to update package - but not sure when exactly it will happen.

If you won't be able to use subscription token generated as described in Centrifugo v5 docs – maybe ask for the help in our communities - https://centrifugal.dev/docs/getting-started/community.

Нет все же дело в .newSubscription, туда как не передавал токены отказывается открывать коннект. Решил через

const centrifuge = new Centrifuge(wss, {
        token: token,
        getToken: async (ctx) => {
            try {
                const response = await fetch(`/api/admin/subscription-token`, {
                    method: 'POST',
                    headers: new Headers({'Content-Type': 'application/json'}),
                    body: JSON.stringify({channel: 'personal:1'})
                });
                const data = await response.json()
                return data.token;
            } catch (e) {
                console.log(e)
                return null;
            }
        },
    });

const sub = centrifuge.newSubscription( 'personal:1');

Так он открывает соединение к приватному каналу и получаю 105 при подписке, getSubscription не достает почему-то его. В целом работает, но очень это все странно)))

shimprog commented 10 months ago

Я ошибся тут generateConnectionToken(string $userId = '', int $exp = 0, array $info = [], array $channels = []) в $channels можно передать название каналов и будет подключение и не нужно getToken добавлять, но как не 105 ошибку вопрос