ConnectyCube / connectycube-reactnative-samples

Chat and Video Chat code samples for React Native, ConnectyCube
https://connectycube.com
Apache License 2.0
125 stars 111 forks source link

Create session token for API rest using python #19

Closed AnnBenavides closed 4 years ago

AnnBenavides commented 4 years ago

Hello, first of all sorry for posting here this issue, i didn't found an API rest repository to ask there. So if it's a problem placing this here just tell me an i'll delete this post.

Then, my issue is to make an API rest with Tornado (Python) and i have problems with the signature (i guess?) in the first step of creating a session token.

Let me show you my code on python 3.6:

Given that, this is my current error, after calling the POST method:

File "<path>\endpoints\session.py", line 102, in post_create_session
    response = await self.application.http_client.fetch(request)
tornado.httpclient.HTTPClientError: HTTP 422: Unprocessable Entity
ERROR:tornado.access:500 POST /session (::1) 71713.50ms

With the follow parameters:

  parameters = {
            'application_id': #string X,
            'auth_key': #string Y,
            'timestamp': '1572908532',
            'nonce': '4102983623',
            'signature': 'GzBqTXHpNcHXJJTVQib0fLkywmE='
        }

So i think there is a problem with the signature generator, but i don't know what to fix. Can you help me?

DaveLomber commented 4 years ago

Here is a working Python example

import time, random, hmac, urllib, httplib
from hashlib import sha1

nonce = str(random.randint(1, 10000))
timestamp = str(int(time.time()))

signature_raw_body = ("application_id=" + application_id + "&auth_key=" + auth_key + 
            "&nonce=" + nonce + "&timestamp=" + timestamp)

signature = hmac.new(auth_secret, signature_raw_body, sha1).hexdigest()

params = urllib.urlencode({'application_id': application_id, 
                           'auth_key': auth_key, 
                           'timestamp': timestamp, 'nonce' : nonce,
                           'signature' : signature})

conn = httplib.HTTPSConnection("api.connectycube.com")
conn.request("POST", "/session", params, {})
response = conn.getresponse()

Regarding your solution - what I can say so far is the signature looks a bit shorter, could you try the one from our example and check

AnnBenavides commented 4 years ago

@DaveLomber thank you, it was a great guide. If someone has the same issue, here is my working code for tornado:

    def hash_hmac_sha1(self, str_input, secure_secret):
        byte_secure = bytearray(secure_secret, 'utf-8')
        byte_input = bytearray(str_input, 'utf-8')
        signature = hmac.new(byte_secure, byte_input, sha1).hexdigest()
        return signature

    def generate_signature(self, user_login, user_pwd):
        nonce = str(random.randint(1, 10000))
        timestamp = str(int(time.time()))
        signature_params = 'application_id={}&auth_key={}&nonce={}&timestamp={}'.format(
            self.app_id, self.auth_key, nonce, timestamp
        )
        if user_login is None or user_pwd is None:
            signature_string = '{}'.format(signature_params)
        else:
            signature_user = 'user[login]={}&user[password]={}'.format(user_login, user_pwd)
            signature_string = '{}&{}'.format(signature_params, signature_user)

        signature = self.hash_hmac_sha1(signature_string, self.auth_secret)
        return timestamp, nonce, signature

    async def post_create_session(self): #TODO test
        url = "{}/{}".format(self.API_HOST, 'session')
        gen = self.generate_signature(None, None)
        parameters = {
            'application_id': '{}'.format(self.app_id),
            'auth_key': self.auth_key,
            'nonce': gen[1],
            'timestamp': gen[0],
            'signature': gen[2]
        }
        h = httplib2.Http()
        resp, content = h.request(url, "POST", body=urlencode(parameters))
        if resp.get('status') == '200':
            self.set_status(200)
            self.finish({
                'results': json.loads(content.decode('utf-8'))
            })
        if resp.get('status') == '201':
            self.set_status(201)
            self.finish({
                'results': json.loads(content.decode('utf-8'))
            })
        else:
            self.set_status(resp.status)
            self.finish({'error': json.loads(content.decode('utf-8'))})
sarpedon333 commented 3 years ago

@DaveLomber i believe the api has changed since this issue has been closed. i have tried the proposed approach in here and creating a session for a specific user results in error!