We are aware of the issue with the badge emails resending to everyone, we apologise for the inconvenience - learn more here.
Forum Discussion
polarzero
2 years agoHelpful | Level 5
Requests always fail from deployed website, but work fine in localhost
I'm using the SDK for requests from my Next.js website. Everything works fine in localhost, but as soon as it is deployed on Vercel, I can only get 400 Errors for my requests to the API. See the ...
- 2 years ago
Thank you for this additional guidance.
I could not make it work at first, but found a solution. For anyone else, new to making this kind of API calls and relying too much on abstracted calls with the SDK (like me), the data needs to be encoded before being passed to the body.
const data = { grant_type: 'refresh_token', refresh_token: refreshToken, client_id: clientId, client_secret: clientSecret, }; const response = await fetch(`https://api.dropboxapi.com/oauth2/token`, { method: 'POST', headers: { 'content-type': 'application/x-www-form-urlencoded', }, // Note this: the data needs to be encoded first! body: new URLSearchParams(data), }); console.log(await response.json());
Thanks again for your concern and patience!
Greg-DB
2 years agoDropbox Staff
I see you're supplying a refresh token, app key, and app secret to the Dropbox JavaScript SDK. In that case, the SDK should automatically use those to retrieve a new short-lived access token (the string that starts with "sl.") whenever needed, which it would then use to perform Dropbox API calls (such as usersGetSpaceUsage).
As you pointed out, in the failing case it appears to be lacking an access token.
In the last screenshot you provided, I see what appears to be the call to use the refresh token to get an access token (with the 'grant_type' and 'refresh_token' parameters), however it looks like it's being made to your app's "/admin/dashboard" path, instead of the Dropbox token endpoint "https://api.dropboxapi.com/oauth2/token" as is necessary to receive the access token from Dropbox.
It's not clear why that is using the wrong URL though. It is technically possible to change the domain (relevant code here and here, meant for internal testing), but that should only change the domain and not the path. From the code you shared though, I don't see you changing that setting anyway. Is the code posted on GitHub exactly what is being run the failing case? Otherwise, is there anything on that environment that would be rewriting requests?
- polarzero2 years agoHelpful | Level 5
Hi Greg. Thanks a lot for taking the time to help me.
The code in the repository is the exact one being used for the deployment (with Vercel), and as you could see I'm using a minimal setup. The only other API requests I'm using are made through Google Drive and Auth0 endpoints.
There is one thing I could think of, but I'm uncertain if it's relevant. Some pages are protected, and can only be accessed if the user is connected. And /admin/dashboard is one of them.
Therefore, navigating to this page, while not being connected, redirects to the Auth0 authentification page AUTH0_ISSUER_BASE_URL. On successful login, the user is sent back to the page.
However, I've just tried making that page public again. It does not solve the issue, though I'm getting a different error, similar to what you've seen on the Vercel screenshot:
So it does make the issue a bit more specific. It looks like I should find out why these requests are not made to the Dropbox API url, though they are on localhost, and how to fix it.
I will try tweaking that domain tomorrow in the morning, it's getting late already here. Maybe I can get it back to the original one, though I did not change it. And I'll try to completely remove other libraries to isolate the problem.
Thanks again for your help! I'll keep you updated, if I were to find any lead!
- polarzero2 years agoHelpful | Level 5
Hi Greg, I finally found a fix. I still have no idea why this request URL was changed, but most important was to get it working.
I had to make a direct request to the API (with the precise URL) to get a temporary access token, then create the Dropbox instance with it. Thereafter, I can keep the same system for making requests, since the only mismatch in the URL was related to the refresh token request. Some pieces of code, in case someone runs into the same issue:
export const getDropboxApiClient = async () => { // Get the refresh token, client ID and secret const refreshToken = process.env.NEXT_PUBLIC_DROPBOX_REFRESH_TOKEN; const clientId = process.env.NEXT_PUBLIC_DROPBOX_APP_KEY; const clientSecret = process.env.NEXT_PUBLIC_DROPBOX_APP_SECRET; // Make the call with a specific address const response = await fetch( `https://api.dropboxapi.com/oauth2/token?grant_type=refresh_token&refresh_token=${refreshToken}&client_id=${clientId}&client_secret=${clientSecret}`, { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: null, }, ); const data = await response.json(); const token = data.access_token; // Create the instance with that access token const dbx = new Dropbox({ accessToken: token }); return dbx; };
And then I can make requests the same way as before:
const dbx = await getDropboxApiClient(); const availableSpace = await dbx.usersGetSpaceUsage();
The only issue here is that my private keys (refresh token, app ID and secret) are visible in the Headers, when navigating to the request headers, in the Debugger. But I'm sure I'll find a quick fix to that.
Thanks a lot for your help, I had given up already before you pointed me to the right direction.
- Greg-DB2 years agoDropbox Staff
Thanks for following up, and for sharing your code. It does seem like something is rewriting those requests but unfortunately I can't say what that might be. In any case, I'm glad to hear you got this working.
By the way, the /oauth2/token endpoint does accept these parameter either on the URL or in the body, so for example (using curl for illustration), instead of:
curl -X POST "https://api.dropboxapi.com/oauth2/token?refresh_token=REFRESH_TOKEN&grant_type=refresh_token&client_id=APP_KEY&client_secret=APP_SECRET"
you can do:
curl -X POST "https://api.dropboxapi.com/oauth2/token" --data "refresh_token=REFRESH_TOKEN&grant_type=refresh_token&client_id=APP_KEY&client_secret=APP_SECRET"
(The "content-type" would be "application/x-www-form-urlencoded".)
- polarzero2 years agoHelpful | Level 5
Thank you for this additional guidance.
I could not make it work at first, but found a solution. For anyone else, new to making this kind of API calls and relying too much on abstracted calls with the SDK (like me), the data needs to be encoded before being passed to the body.
const data = { grant_type: 'refresh_token', refresh_token: refreshToken, client_id: clientId, client_secret: clientSecret, }; const response = await fetch(`https://api.dropboxapi.com/oauth2/token`, { method: 'POST', headers: { 'content-type': 'application/x-www-form-urlencoded', }, // Note this: the data needs to be encoded first! body: new URLSearchParams(data), }); console.log(await response.json());
Thanks again for your concern and patience!
About Dropbox API Support & Feedback
Find help with the Dropbox API from other developers.
5,877 PostsLatest Activity: 12 months agoIf you need more help you can view your support options (expected response time for an email or ticket is 24 hours), or contact us on X or Facebook.
For more info on available support options for your Dropbox plan, see this article.
If you found the answer to your question in this Community thread, please 'like' the post to say thanks and to let us know it was useful!