【问题标题】:Unable to connect to Room: Invalid Access Token issuer/subject - Twilio visio room issues无法连接到房间:无效的访问令牌颁发者/主题 - Twilio visio 房间问题
【发布时间】:2021-01-30 03:20:06
【问题描述】:

在这个教程的帮助下,我正在使用 twilio,Symfony 5: https://www.twilio.com/blog/create-group-video-chat-app-symfony-php-twilio-react 创建视频聊天。

在输入房间名称并启动 visio 时,我在浏览器的控制台中收到以下错误:

Unable to connect to Room: Invalid Access Token issuer/subject

我理解是因为路由access_token生成的token一定不对。

我创建了一个普通的 twilio 帐户,然后生成了 API 密钥,并在我的 .env 文件中保存了帐户 sid、api 密钥 sid 和 api 机密。

以防万一我重新创建了一个新的 api 密钥以查看它是否更改了某些内容但没有更改。

我已检查文档是否有错误 (https://www.twilio.com/docs/api/errors/20103),但解决方案并未解决我的问题。

Chat.js文件:

import React, { useState } from "react";
import axios from "axios";
import Video from "twilio-video";

const Chat = () => {
    const [roomName, setRoomName] = useState('');
    const [hasJoinedRoom, setHasJoinedRoom] = useState(false);

    const joinChat = event => {
        event.preventDefault();
        if (roomName) {
            axios.post('/access_token', { roomName }, ).then((response) => {
                console.log('RESPONSE: ');
                console.log(response.data.token);
                connectToRoom(response.data.token);
                setHasJoinedRoom(true);
                setRoomName('');

            }).catch((error) => {
                console.log(error);
            })
        } else {
            alert("You need to enter a room name")
        }
    };

    const connectToRoom = (token) => {
        const { connect, createLocalVideoTrack } = Video;
        let connectOption = { name: roomName };

        connect(token, connectOption).then(room => {
            console.log(`Successfully joined a Room: ${room}`);
            const videoChatWindow = document.getElementById('video-chat-window');

            createLocalVideoTrack().then(track => {
                videoChatWindow.appendChild(track.attach());
            });
            room.on('participantConnected', participant => {
                console.log(`Participant "${participant.identity}" connected`);
                participant.tracks.forEach(publication => {
                    if (publication.isSubscribed) {
                        const track = publication.track;
                        videoChatWindow.appendChild(track.attach());
                    }
                });
                participant.on('trackSubscribed', track => {
                    videoChatWindow.appendChild(track.attach());
                });
            });
        }, error => {
            console.error(`Unable to connect to Room: ${error.message}`);
        });
    };

    return(
        <div className="container">
            <div className={"col-md-12"}>
                <h1 className="text-title">Symfony React Video Chat</h1>
            </div>

            <div className="col-md-6">
                <div className={"mb-5 mt-5"}>
                    {!hasJoinedRoom && (
                        <form className="form-inline" onSubmit={joinChat}>
                            <input type="text" name={'roomName'} className={"form-control"} id="roomName"
                                   placeholder="Enter a room name" value={roomName} onChange={event => setRoomName(event.target.value)}/>

                            <button type="submit" className="btn btn-primary">Join Room</button>

                        </form>
                    )}

                </div>



                <div id="video-chat-window"/>
            </div>
        </div>
    )
};

export default Chat;

TokenController 文件生成用户令牌:

<?php

namespace App\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Annotation\Route;
use Twilio\Jwt\AccessToken;
use Twilio\Jwt\Grants\VideoGrant;

class TokenController extends AbstractController
{

    /**
     * @Route("/token", name="token")
     */
    public function index()
    {
        return $this->render('token/index.html.twig', [
            'controller_name' => 'TokenController',
        ]);
    }

    /**
     * @param Request $req
     * @return \Symfony\Component\HttpFoundation\JsonResponse
     * @Route("access_token", name="access_token", methods={"POST"})
     */
    public function generateToken(Request $req) {

        $accountSid = getenv('ACCOUNT_SID');
        $apiKeySid = getenv('API_SID'); 
        $apiKeySecretSid = getenv('API_SECRET');

        $identity = uniqid();

        $roomName = json_decode($req->getContent());

        $token = new AccessToken(
            $accountSid,
            $apiKeySid,
            $apiKeySecretSid,
            3600,
            $identity
        );

        $grant = new VideoGrant();
        $grant->setRoom($roomName->roomName);
        $token->addGrant($grant);
        return $this->json(['token' => $token->toJWT()], 200);
    }
}

**app.js**中的这一行:

ReactDOM.render(<Chat/>, document.getElementById("root"));

使用正确的导入。

更新

找到解决方案!感谢您的帮助!

getenv() 方法是问题所在。

我现在将我的 .env 信息作为参数注入到我的控制器中,如下所示:

services.yaml

parameters:
    app.env.ACCOUNT_SID: '%env(resolve:ACCOUNT_SID)%'
    app.env.API_KEY: '%env(resolve:API_KEY)%'
    app.env.API_SECRET: '%env(resolve:API_SECRET)%'

并在控制器中恢复它们

Controller to recover the data


public function somename() {
    
    $sid = $this->getParameter('app.env.ACCOUNT_SID');
    $apiKey = $this->getParameter('app.env.API_KEY');
    $apiSecret = $this->getParameter('app.env.API_SECRET');

    $identity = uniqid();

    $token = new AccessToken(
        $sid,
        $apiKey,
        $apiSecret,
        3600,
        $identity
    );
}

而且像魅力一样工作

【问题讨论】:

  • DotEnv 组件及其注册变量的方式最近发生了变化,您是否检查过它们在控制器上是否正确设置?
  • 他们做了哪些改变?事实上,如果我将生成的令牌粘贴到 jwt.io 上,则令牌无效。知道为什么吗?
  • 它不会使用putenv 注册变量,因此您的getenv 调用可能会返回false(请参阅herehere)。尝试转储变量以检查它。 twilio-sdk 中没有针对空值的保护措施。
  • 好的,谢谢您的帮助,问题就出在这里。由于 getenv,生成的令牌没有我的帐户 ID、api 密钥和秘密。我会试着找到自己的路
  • 在你的配置和inject ParameterBag or the individual values中创建参数。

标签: reactjs symfony twilio


【解决方案1】:

也许它可以帮助那些有这个问题的人。

我发现示例代码中使用的默认区域是“US1”,并且我已经在“IE1”区域中创建了我的 API KEY。 创建和使用在 US1 地区制造的 API KEY 解决了我的问题并使示例代码工作。

现在因为我在欧洲地区,所以我将尝试弄清楚如何在 SDK 中将默认地区设置为“IE1”。

【讨论】:

    猜你喜欢
    • 2021-03-03
    • 2021-05-17
    • 2021-03-02
    • 2020-12-02
    • 2020-08-14
    • 2020-05-06
    • 2020-11-23
    • 2020-01-26
    • 2018-03-17
    相关资源
    最近更新 更多