We are aware of the issue with the badge emails resending to everyone, we apologise for the inconvenience - learn more here.
Forum Discussion
fietserwin
4 years agoExplorer | Level 4
What way of authorization to use for a (PHP) open source module
I am the developer of the Drupal module Backup & migrate Dropbox that extends the "Backup and migrate" module to store backups on Dropbox. So this module: is open source, so I cannot put the App se...
- 4 years ago
While the PKCE flow is generally meant for client-side apps (and server-side apps would generally use the code flow) given the constraints in this case, using the PKCE flow seems reasonable and should work.
The issue you're running in to here is that you're calling /oauth2/token to perform 'grant_type=refresh_token' but are supplying the 'code_verifier' parameter. The 'code_verifier' parameter should only be provided for the initial 'grant_type=authorization_code'.
That is, the flow should look like this:
- The user is directed to /oauth2/authorize
- The user approves the app
- The user copies the authorization code from the Dropbox web site into the app
- The app calls /oauth2/token supplying 'code' set to the authorization code, 'grant_type=authorization_code', 'code_verifier' set to the code verifier, and 'client_id' set to the app key, just once per authorization flow.
- The app uses the short-lived access token to make API calls.
- The app calls /oauth2/token supplying 'refresh_token' set to the refresh token, 'grant_type=refresh_token', and 'client_id' set to the app key, but not 'code_verifier', repeatedly whenever a new short-lived access token is needed.
Also, to confirm, yes, refresh tokens are long-lived. They don't expire by themselves, but can be revoked on demand.
Hope this helps!
Greg-DB
Dropbox Staff
While the PKCE flow is generally meant for client-side apps (and server-side apps would generally use the code flow) given the constraints in this case, using the PKCE flow seems reasonable and should work.
The issue you're running in to here is that you're calling /oauth2/token to perform 'grant_type=refresh_token' but are supplying the 'code_verifier' parameter. The 'code_verifier' parameter should only be provided for the initial 'grant_type=authorization_code'.
That is, the flow should look like this:
- The user is directed to /oauth2/authorize
- The user approves the app
- The user copies the authorization code from the Dropbox web site into the app
- The app calls /oauth2/token supplying 'code' set to the authorization code, 'grant_type=authorization_code', 'code_verifier' set to the code verifier, and 'client_id' set to the app key, just once per authorization flow.
- The app uses the short-lived access token to make API calls.
- The app calls /oauth2/token supplying 'refresh_token' set to the refresh token, 'grant_type=refresh_token', and 'client_id' set to the app key, but not 'code_verifier', repeatedly whenever a new short-lived access token is needed.
Also, to confirm, yes, refresh tokens are long-lived. They don't expire by themselves, but can be revoked on demand.
Hope this helps!
fietserwin
4 years agoExplorer | Level 4
Yes, that works, thanks a lot. I thus indeed was close all that time. Could it be an idea to add a step 6 to the PKCE guide (https://dropbox.tech/developers/pkce--what-and-why-) or add a 4th example to https://www.dropbox.com/developers/documentation/http/documentation#oauth2-token ?
- delahoc4 years agoExplorer | Level 4
I'm not having any joy at all getting authorisation to work. As far as I can tell, I'm following the docs to the letter (though some of them are extremely difficult to read or interpret) and this coincides perfectly with the steps outlined earlier in this thread.
I'm trying to use the PKCE flow for a Wordpress plugin built in PHP. The docs say this is the best method to use where the code will be viewable by the public so you don't want to have your app secret used.
I construct a url to take the user to oauth2/authorize to authorise the app. The url has the following added in correct url encoded format:
response_type=code
client_id=<MYAPPID>
code_challenge=<CHALLENGE>
code_challenge_method=S256
(with the appropriate values in place of the placeholders above).
The user then returns to my app and types in the <CODE> they're given, and I then save it.
I then immediately use that <CODE> to try to get a token using oauth2/token. I'm using CURL for this. The headers I set are:
Accept: application/json Content-Type: application/x-www-form-urlencoded
Then for the data (sent in urlencoded format) I have
code=<CODE>
grant_type=authorization_code
code_verifier=<CHALLENGE>
client_id=<MYAPPID>What I get back from Dropbox, though, is an error:
{"error_description": "invalid code verifier", "error": "invalid_grant"}
I keep trying different combinations of things, including with the headers, for about five minutes until the <CODE> expires and the error message changes to that. Then I have to re-authorise the app and circle around again. The encrypted code verifier I'm sending in the token request is exactly the same encrypted code verifier I sent with the authorisation url. So why the error?
This is doing my head in. Can anyone please help?
- fietserwin4 years agoExplorer | Level 4
Delahoc,
I suggest you have a look at my code that you can find at https://www.drupal.org/project/backup_migrate_dropbox/releases/7.x-3.0, that should help you to construct the correct flow and requests and process the answers.
- delahoc4 years agoExplorer | Level 4
Thanks for the reply. I'm pretty sure I have the flow and requests correct. I'd love to check out your code, but that link you've provided gives a 404 Page Not Found error.
About Discuss Dropbox Developer & API
Make connections with other developers
795 PostsLatest Activity: 8 days 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!