TikTok business API: OAuth2 authorization code is always expired

190 views Asked by At

I'm trying to write a Python script that interacts with TikTok's API (mistake). I've got some code that seems to almost work, but the API is responding to my access_token request that the authorization code is expired, moments after the code is generated, so I'm unable to get a token at all.

I have the following code for getting an authorisation URL, getting the auth code out of it and sending it off to exchange for an access token:

# API key details
token_url = "https://open.tiktokapis.com/v2/oauth/token/" 
auth_url =  "https://business-api.tiktok.com/portal/auth"
redirect_uri = "https://my_company_website/"

app_id = "xxxxxxxxxx"
secret_key = "yyyyyyyyyy"

def generate_auth_url():
    csrf_state = secrets.token_hex(16)

    params = {
        'app_id': app_id,
        'scope': 'user.info.basic',
        'redirect_uri': redirect_uri,
        'state': csrf_state,
    }

    url = auth_url + '?' + urllib.parse.urlencode(params)
    
    return url, csrf_state
    
# Function to get the access token
def get_access_token(authorization_code):
    data = {
        'client_key': app_id,
        'client_secret': secret_key,
        'code': authorization_code,
        'grant_type': 'authorization_code',
        'redirect_uri': redirect_uri
    }
    headers = {
        'Content-Type': 'application/x-www-form-urlencoded'
    }

    response = requests.post(token_url, headers=headers, data=urllib.parse.urlencode(data))

    if response.status_code == 200:
        return response.json()
    else:
        print(f"Error: Received status code {response.status_code}")
        print(f"Response content: {response.content.decode()}")
        return None

def manual_test():
    # Generate authorization URL
    print("Generating authorization URL...")
    url, state = generate_auth_url()
    print("URL:", url)
    print("State:", state)
    
    # Prompt user for the redirect URL
    input_ = input("Paste the URL you were redirected to: ")
    
    # Extract authorization code from redirect URL
    code = input_.split("code=")[1].split("&")[0]

    # Decode the code (THAT'S THE EDITING PART) 
    decoded_code = urllib.parse.unquote(code)

    print("Code:", code)
    print("Decoded Code:", decoded_code)
    
    # Fetch access token without delay
    print("Fetching access token...")
    token_info = get_access_token(decoded_code)
    print(token_info)

But sending the request for a token off leads to the error code:

{'error': 'invalid_grant', 'error_description': 'Authorization code is expired.', 'log_id': '202312191447256251E59DA270380F9108'}

Which is complete nonsense since auth codes are meant to last 24 hours per their documentation.

I'm aware that the parameters are different in the two requests (app_id becomes client_key in the access token request, whereas on my app details, the parameters are referred to as app_id and secret rather than cleint_key and client_secret), but it needs to be referred to as app_id in the first part to get the authorization URL, and having any parameter names other than client_key and client_secret in the second part results in an invalid parameters error. Which makes me concerned that I'm using the wrong access_token URL, but there aren't any other token URLs in existence according to TikTok's documentation.

Does anyone know what's going wrong here?

1

There are 1 answers

0
Virginie Cazol On

I had the same issue using NodeJS and Axios. Try this:

token_url = "https://business-api.tiktok.com/open_api/v1.3/oauth2/access_token/" 

data = {
        'app_id': app_id,
        'secret': secret_key,
        'auth_code': authorization_code,
        'grant_type': 'authorization_code', // you can remove this
        'redirect_uri': redirect_uri // you can remove this
    }
    headers = {
        'Content-Type': 'application/application/json'
    }

    response = requests.post(token_url, headers=headers, data=urllib.parse.urlencode(data))