Reputation: 305
I'm using twilio, Symfony 5 with the help of this tuto : https://www.twilio.com/blog/create-group-video-chat-app-symfony-php-twilio-react to create a video chat.
Upon entering the name of the room and launching the visio, I got the following error in the browser's console :
Unable to connect to Room: Invalid Access Token issuer/subject
I understand it's caused because the token generated by the route access_token must not be right.
I've created a normal twilio account then generated the API key, kept account sid, api key sid and api secret on my .env file.
Just in case I recreated a new api key to see if it changed something but didn't.
I've checked the doc for my error (https://www.twilio.com/docs/api/errors/20103) , but the solutions did not solve my problem.
Chat.js
file:
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
file to generate user's token :
<?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);
}
}
And this line in the **app.js**
:
ReactDOM.render(<Chat/>, document.getElementById("root"));
With the proper imports.
Solution found! Thanks for the help !
getenv() method was the issue.
I now inject my .env info in my controller as parameters as follow :
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)%'
And recover them in the controller
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
);
}
And works like a charm
Upvotes: 3
Views: 5092
Reputation: 61
may be it could help those who has this issue.
I have found that the default region used in the exemple code was "US1" and that I have create my API KEY in the region "IE1". Creating and using an API KEY made in the US1 region has resolve my problem and has made the exemple code work.
Now because I am in Europe region, i will try to figure how to set the default region as "IE1" in the SDK.
Upvotes: 6