3

I'm trying to exchange my authorization token for a bearer token. According to the docs it should be a application/x-www-form-urlencoded request. My code looks like this:

$res = Http::withHeaders([
    'Accept'       => 'application/json',
    'Content-Type' => 'application/x-www-form-urlencoded',
    'Cache-Control' => 'no-cache'
])->post('https://open.tiktokapis.com/v2/oauth/token/', [
    'client_id'    => 'my-client-id',
    'client_secret' => 'my-client-secret',
    'code'          => $request->code,
    'grant_type'    => 'authorization_code',
    'redirect_uri'  => 'https://example.com/callback/tiktok',
]);

I keep receiving:

{"error":"invalid_request","error_description":"The request parameters are malformed.","log_id":"20230621065239FB74CE96D69DA40A2B46"}

What could be going on here? Already tried contacting tiktok a week ago but no response.

Jamie
  • 10,302
  • 32
  • 103
  • 186

4 Answers4

2

I finally found the answer to this - at least in my case.

When upgrading to the V2 OAuth flow, I had only upgraded the token endpoint for the server (https://open-api.tiktok.com/oauth/access_token > https://open.tiktokapis.com/v2/oauth/token) but forgotten to add the /v2 path to the original authorization endpoint for the user. This is easy to miss as the websites look exactly the same.

v1/Legacy:

https://www.tiktok.com/auth/authorize?client_key=xxxx&redirect_uri=https://...

v2/:

https://www.tiktok.com/v2/auth/authorize?client_key=xxxx&redirect_uri=https://...

After changing this, I no longer receive the malformed parameters error and it seems to work as expected. Leaving this here in case it helps someone else. I don't know how I missed this when it's in the migration guide.

nickdnk
  • 4,010
  • 4
  • 24
  • 43
1

Illuminate\Support\Facades\Http facade seems to create some problems with the internal protected variable $bodyFormat of Illuminate\Http\Client\PendingRequest class as it creates the instance of this class internally while making requests.

You could rather directly use PendingRequest class to make requests like below:

Snippet:

<?php

use Illuminate\Http\Client\PendingRequest; 

$o = new PendingRequest();
$o->asForm(); // to set content type header to application/x-www-form-urlencoded

$res = $o->post('https://open.tiktokapis.com/v2/oauth/token/', [
  'client_key'    => 'CLIENT_KEY', // your value here
  'client_secret' => 'CLIENT_SECRET', // your value here
  'code'          =>  'CODE', // your value here
  'grant_type'    => 'authorization_code',
  'redirect_uri'  => 'https://example.com/callback/tiktok' // your value here
]);

dd($res->body());

Online Demo

nice_dev
  • 17,053
  • 2
  • 21
  • 35
  • thank you very much for sorting out the problem! Appreciate it very much. When I try this I receive the same 'malformed' error. When I enter my information in your online demo I get the same error. Double checked my information and seems to be fine. This is so weird. Maybe a bug? – Jamie Jun 21 '23 at 08:48
  • @Jamie I receive a different response in my online demo. It just needs correct values of those params to fetch the data I presume. Would you mind to share? – nice_dev Jun 21 '23 at 08:50
  • Sure do you have something where I can send them to? I will change them afterwards. – Jamie Jun 21 '23 at 08:52
  • Rather just paste a new link of the demo site with your inserted credentials here. For a quick resolution, you can use PHP cURL to move ahead with your development. – nice_dev Jun 21 '23 at 08:54
  • @Jamie cURL version. Just replace the values with yours and should work just fine https://pastebin.com/Ee6NUqjx – nice_dev Jun 21 '23 at 08:58
  • https://laravelplayground.com/#/snippets/1b2b71aa-71b4-4d28-b4b9-e1c2e3398656 – Jamie Jun 21 '23 at 08:59
  • @Jamie Ok, it says `Authorization code is expired`. So you will have to create a new one and try again. – nice_dev Jun 21 '23 at 08:59
  • @Jamie See https://developers.tiktok.com/doc/oauth-error-handling/#:~:text=unsupported%20authentication%20method).-,invalid_grant,-The%20provided%20authorization – nice_dev Jun 21 '23 at 09:00
  • Yes I know every time I test I add a new authorization code I receive via my site. That's not the problem unfortunately. – Jamie Jun 21 '23 at 09:02
  • I have this problem as well and I have no idea how to solve it. All other OAuth flows we have work as expected, but TikTok keeps giving me "The request parameters are malformed" even though what I send them is perfectly valid. I don't understand what your solution is here. I use Guzzle and that takes care of all encoding for me. It also worked fine on their v1/legacy oauth, but their v2 doesn't work. – nickdnk Jun 26 '23 at 17:11
  • @nickdnk ok, my current code gives authorization errors which means the request parameters are no longer malformed. So OP' s issue should get solved. To solve the authorization issues, it obviously needs actual client live tokens. You can try this at your end. – nice_dev Jun 26 '23 at 18:37
  • 1
    @nice_dev You'll get "Authorization code is expired" **before** you get "The request parameters are malformed.", as in if your code parameter is invalid or expired, you won't reach the original problem at all, which from an implementation perspective is nonsense. I am of course using my own app's parameters, and they worked fine for TikTok's v1 OAuth, but I simply can't get v2 to work. I tried doing this with Postman manually, and it also does not work there. Edit: I think I'll have to stay on v1 until TikTok resolves this issue. – nickdnk Jun 26 '23 at 20:21
  • Funny thing is that this **does** work when using their mobile SDK. The difference here is that the mobile SDK generates a **code_verifier** parameter which you're supposed to send along with the **code** when exchanging for a token - and this works. I tried adding an empty **code_verifier** parameter with the web-based flow as I figured maybe they expect it to be there but just be empty, but that still gives the same malformed parameters error. – nickdnk Jul 03 '23 at 14:44
  • So update on this. The reason it worked on the mobile flow was because I used the TikTok app/SDK for this, and on my web integration I had forgotten to add `/v2` to the oauth link on TikTok, so I was essentially mixing the v1 and v2 flows. I added an answer for this. – nickdnk Jul 25 '23 at 18:42
0

I was facing the same issue earlier. I had to encode the body parameters, and after that, it worked. PHP is not my first language, but maybe you can try something like this:

$res = Http::withHeaders([
    'Accept'       => 'application/json',
    'Content-Type' => 'application/x-www-form-urlencoded',
    'Cache-Control' => 'no-cache'
])->post('https://open.tiktokapis.com/v2/oauth/token/', http_build_query([
    'client_key'    => 'my-client-id',
    'client_secret' => 'my-client-secret',
    'code'          => $request->code,
    'grant_type'    => 'authorization_code',
    'redirect_uri'  => 'https://example.com/callback/tiktok',
]));
  • But `post` expects 2nd param to be an array. https://laravel.com/api/9.x/Illuminate/Http/Client/PendingRequest.html#method_post – nice_dev Jun 21 '23 at 08:48
  • When I try to append it like a query I get the same error -_- – Jamie Jun 21 '23 at 08:50
0

1st thing to do is URL-encode the parameters:

$params = http_build_query([
    'client_id'     => 'my-client-id',
    'client_secret' => 'my-client-secret',
    'code'          => $request->code,
    'grant_type'    => 'authorization_code',
    'redirect_uri'  => 'https://example.com/callback/tiktok',
]);

$res = Http::withHeaders([
    'Accept'       => 'application/json',
    'Content-Type' => 'application/x-www-form-urlencoded',
    'Cache-Control' => 'no-cache'
])->post('https://open.tiktokapis.com/v2/oauth/token/', $params);

Then you can:

  • Check all the required parameters are provided and valid.
  • Ensure that the endpoint URL is correct.
  • Check if the TikTok API version (v2) is correct.
Wakil Ahmed
  • 1,053
  • 1
  • 8
  • 16