0

Running a Django rest api with Tokbox in a Debian Server. I was running it through a python virtual enviroment which was working fine, but need to take it out of the enviroment for a few reasons. When I did so, after installin all dependencies and got it running got the following error:

raise RequestError('Failed to create session: %s' % str(e))

opentok.exceptions.RequestError: Failed to create session: Failed to create session, invalid credentials

Both keys are saved as enviroment variables and brought back correctly, I can log them and they are correct. Also if I turn on the python virtual enviroment again the error disappears.

For the record, the lines of my code that cause the error are:

opentok = OpenTok(api_key, api_secret)
session = opentok.create_session(media_mode=MediaModes.routed)

The function that raises the exception in the source code is the following:

try:
        response = requests.post(self.session_url(), data=options, headers=self.headers(), proxies=self.proxies)
        response.encoding = 'utf-8'

if response.status_code == 403:
            raise AuthError('Failed to create session, invalid credentials')

At first I thought it had to be some sort of encryption or hashing that was done to the api key and api secret. And Tokbox does indeed use jwt for that, but it is done in a function called by the constructor and therefore also being done when I dont use the virtual enviroment. The function headers() called above in the request is the following:

def headers(self):
    """For internal use."""
    return {
        'User-Agent': 'OpenTok-Python-SDK/' + __version__ + ' ' + platform.python_version(),
        'X-OPENTOK-AUTH': self._create_jwt_auth_header()
    }

def _create_jwt_auth_header(self):
    payload = {
                  'ist': 'project',
                  'iss': self.api_key,
                  'iat': int(time.time()), # current time in unix time (seconds)
                  'exp': int(time.time()) + (60*3), # 3 minutes in the future (seconds)
                  'jti': '{0}'.format(0, random.random())
              }

    return jwt.encode(payload, self.api_secret, algorithm='HS256')
Pablo Duque
  • 383
  • 2
  • 20
  • The only thing that comes to mind is that maybe the time is out of sync when you're using the different environment which is making the JWT expire or be in the past or something. Is that possible? – Adam Ullman Sep 19 '17 at 06:56
  • @AdamUllman Date and time seem correct both in and out of the venv. Any other idea? – Pablo Duque Sep 19 '17 at 07:21
  • @AdamUllman even though time seemed correct, it was indeed a time issue. About to post the solution – Pablo Duque Sep 19 '17 at 13:35

1 Answers1

2

Server time seemed correct but I guess it wasn't. You can solve this by substracting some time from 'iat' in the jwt function. Ended up finding the solution thanks to tokbox support so props to them!

Find where your installation placed the file 'opentok.py' by:

find / -name opentok.py

Then substract 3600 like the following lines show:

def _create_jwt_auth_header(self):
    payload = {
                  'ist': 'project',
                  'iss': self.api_key,
                  'iat': int(time.time()) - 3600, # three minutes ago (seconds)
                  'exp': int(time.time()) + (60*3), # 3 minutes in the future (seconds)
                  'jti': '{0}'.format(0, random.random())
              }

    return jwt.encode(payload, self.api_secret, algorithm='HS256')
Pablo Duque
  • 383
  • 2
  • 20