Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Obtain Access Token seems to fail #151

Closed
pvichivanives opened this issue May 1, 2024 · 8 comments · Fixed by #152
Closed

Obtain Access Token seems to fail #151

pvichivanives opened this issue May 1, 2024 · 8 comments · Fixed by #152
Assignees
Labels
bug Something isn't working

Comments

@pvichivanives
Copy link

pvichivanives commented May 1, 2024

What is your question?
Not sure if I'm missing something or theres a bug with the code but I am unable to fetch access_tokens from the refresh token. I am able to create the Authorization State of refresh token from initialAuth but unable to proceed further.

Screenshots
If applicable, add screenshots to help explain your question.
For this image, we would get an auth code from the login with details from the user and my client secret. The first call would go successfully, going from the state of InitialAuth to RefreshToken. However, any call with the refresh token to get an access_code again (like the second call here) would fail with the error: Dropbox API returned HTTP 400 Bad Request - {"error": "invalid_request", "error_description": "No auth function available for given request"}.
image

Versions

  • What version of the SDK are you using? 0.18.0
  • What version of the language are you using? 1.77.2
  • What platform are you using? Mac OSX

Additional context
For reference this is how I generate the initial dropbox auth request although since it got through the first initialAuth I would assume this isn't the issue
image

@pvichivanives pvichivanives added the question Further information is requested label May 1, 2024
@wfraser
Copy link
Member

wfraser commented May 2, 2024

Can you share what is the Oauth2Type you're using? It's the second parameter to Authorization::from_auth_code(). Redact any secrets of course.

@pvichivanives
Copy link
Author

pvichivanives commented May 2, 2024

Hi! I'm using a client Secret with the app_secret from Dropbox. Thanks!

 let dropbox_client_secret = Oauth2Type::AuthorizationCode {
        client_secret: "secret goes here",
    };

@wfraser
Copy link
Member

wfraser commented May 2, 2024

Thanks. I'm able to reproduce the problem. Apparently refresh tokens obtained using a client secret are different from ones obtained using the PKCE flow, and we need to pass the client secret along with the refresh token when obtaining a new token. This is a difference I wasn't previously aware of.

I'll make a fix to Authorization::obtain_access_token() which does the right thing here for any new authorizations.

From your side, there are a couple options. First, and maybe easiest, you can change to using PKCE instead of the client secret to do the authorization. The code for that doesn't have the bug and is basically identical in every other way. You can actually do that right now before I make a new release with this fix.

If you have existing refresh tokens that you need to keep using, you'll need to pick up the fix for this, and your code will need a slight change, since Authorization doesn't know whether it was obtained using a client secret or not. I'll be adding a new function Authorization::from_client_secret_refresh_token() which takes the client secret as well as the refresh token, and that should work for any existing tokens obtained that way.

@wfraser wfraser added bug Something isn't working and removed question Further information is requested labels May 2, 2024
@wfraser wfraser self-assigned this May 2, 2024
@wfraser
Copy link
Member

wfraser commented May 2, 2024

@pvichivanives do you think you could test this fix and let me know if it works for you? #152

@pvichivanives
Copy link
Author

pvichivanives commented May 2, 2024

@wfraser It works but I think you missed the save/load still needing the client_secret as well. Authorization::load will always pick from_refresh_token (tried extracting refresh token and using it in from_client_secret_refresh_token and that worked)

@wfraser
Copy link
Member

wfraser commented May 2, 2024

If you're using save/load, you really should be using PKCE anyway. The alternative would require saving the secret in there too, which is not a great idea since in the case of a leak, a token can be easily revoked, but the client secret not so much.

@pvichivanives
Copy link
Author

pvichivanives commented May 2, 2024

Would it make sense to have an alternate to save/ save the refresh token without the "2&" if theres a secret? This would make it possible to save refresh token but not put the secret inside and then reuse the token later with the same client id/secret later. An alternative idea would be that load could take in an Option of a secret but then that would be a breaking change.

@wfraser
Copy link
Member

wfraser commented May 6, 2024

Yeah, as you mention, it'd be a breaking change. It'd also break the CLI helper get_auth_from_env_or_prompt() which assumes there are just two env variables, one with client ID and one with the saved string.

However the whole load() function just calls public functions, so if you'd like such functionality, you can roll your own easily.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants