httr icon indicating copy to clipboard operation
httr copied to clipboard

httr::oauth2.0_token$refresh() returns "argument is of length zero"

Open serkor1 opened this issue 3 years ago • 7 comments

I have the following token,

# Credentials
token_type: "bearer"
expires_in: "7200"
access_token: "eyJhbGciOiJFUzI1NiIsImtpZCI6Ijc3ZmJhODY5LTlkMWMtNDk5ZS04ZTJiLTBlNmVkZjdjODA5MiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2MjAxMjkzMjgsImlhdCI6MTYyMDEyMjEyOCwiaXNzIjoidGluazovL2F1dGgiLCJqdGkiOiIyZmM1MjJmNy0wNDUyLTRkZWYtOWU4ZC1lOGJkMTFhMjk1ZWQiLCJvcmlnaW4iOiJtYWluIiwic2NvcGVzIjpbInRyYW5zYWN0aW9uczpyZWFkIl0sInN1YiI6InRpbms6Ly9hdXRoL3VzZXIvMTk3ZmQwMDIxMzc2NDAwYWI2MDBiNWJiMzc3MDllZjUiLCJ0aW5rOi8vYXBwL2lkIjoiZDkyNmExMDViMTY3NDU1OTg0NTFkZmQwNmRiZWJiMWMiLCJ0aW5rOi8vYXBwL3ZlcmlmaWVkIjoiZmFsc2UifQ.PkYx7TGhiDe7H06Tk9W9TUTBMis-a58LQdyhoxZG3Glw78IgbXeMd4WGBZZlcLyCl3mGefsROue47BDGhO6AnA"
refresh_token: "f5d30595e11d447f869398933ce1aafa"
scope: "transactions:read"
id_hint: 

# App
appname: Tink with R
secret: "0c31ae504fda4af78ee64974dba388f9"
key: "8f5f1b32c8f54defa1c9c36fb5ddb86d"
redirect_uri: "http://localhost:1410/"

# Endpoints
request: NULL
authorize: "https://link.tink.com/1.0/authorize/"
access: "https://api.tink.se/api/v1/oauth/token"

Which were generate by,

# Set up test queries;
query_params <- list(
    test = "true",
    market = "GB"
)

# Generate Token;
token <- oauth2.0_token(
               endpoint = api,
               app = app,
               query_authorize_extra = query_params,
               scope = scope,
               credentials = oauth2.0_access_token(
                          api,
                          app,
                          parseQueryString(session$clientData$url_search)$code
                        ),
                cache = TRUE
)

And r token$can_refresh() is TRUE. However, when I use r token$refresh() I get the following error;

Error in if (!content$error %in% oauth2.0_errors) { : 
  argument is of length zero

It was my understanding, according to the documentation, that r token$refresh() should work "out of the box". Examining the source of the function leads to no predictable errors, as the query made is aligned with that of the OAuth workflow.

Am I missing somehting, or is this a bug? I was expecting that using r token$refresh() would refresh the token without the user having to log in!

Im working on a package, that I plan to release as soon as I solve this hurdle.

Best,

Serkan Korkmaz

serkor1 avatar May 04 '21 11:05 serkor1

Your usage of the credentials argument of oauth2.0_token() is highly unusual. With only slight exaggeration, that argument exists strictly for testing purposes.

You're sort of trying to do oauth2.0_token()'s job for it by calling oauth2.0_access_token() yourself and parsing its output.

This search of other R packages on CRAN that use oauth2.0_token() will get some more conventional usage in front your 👀:

https://github.com/search?q=oauth2.0_token+path%3AR+org%3Acran

jennybc avatar May 04 '21 16:05 jennybc

Hi Jenny,

Thank you for your reply. I will re-evaluate my approach. However, I followed Hadley's example found here, so I was under the impression that my approach was bulletproof.

Do you suggest that the error given stems from my approach? Or was that just a comment?

serkor1 avatar May 04 '21 18:05 serkor1

That gist is specifically for a Shiny context and is doing some unconventional things. Are you doing OAuth 2 in Shiny?

Yes, my hunch is that that approach is the root cause of your pain.

jennybc avatar May 04 '21 18:05 jennybc

Ah! Of course, maybe I should have added that. Yes, it is specifically for Shiny! However, the behavior is not consistent. I literally just tried to run token$refresh() and got;

<Token>
<oauth_endpoint>
 authorize: https://link.tink.com/1.0/authorize/
 access:    https://api.tink.se/api/v1/oauth/token
<oauth_app> Tink with R
  key:    8f5f1b32c8f54defa1c9c36fb5ddb86d
  secret: <hidden>
<credentials> token_type, expires_in, access_token, refresh_token, scope
---

Im not sure what to make of it really.

serkor1 avatar May 04 '21 18:05 serkor1

Yes, it is specifically for Shiny!

Well, in that case, I'll pipe down as I haven't really digested that gist. But I imagine it does represent a certain amount of ... creative problem-solving, i.e. use of httr that was not planned from the beginning. So it's not a shock that "your mileage may vary", with a different API, etc.

jennybc avatar May 04 '21 19:05 jennybc

Hi Jenny!

Ive been experimenting a bit. And wanted your feedback - it appears that the option to refresh expires after some point. Am I correct to assume that once you refresh, the resulting token should be your new token, which you then can refresh such that it recursively updates itself, until API requests a new login?

I'm not entirely into the terminology; so I hope my question is clear. If not Ill clarify further!

serkor1 avatar May 06 '21 09:05 serkor1

Here's a good explainer of the vocabulary:

https://auth0.com/learn/refresh-tokens/

Although it feels backwards to me, the refresh token is the less perishable thing (although they can also be revoked or rendered invalid in many ways). Generally refresh tokens have some persistence and are what allows you to get new access tokens, which are highly perishable.

jennybc avatar May 06 '21 16:05 jennybc

httr has been superseded in favour of httr2, so is no longer under active development. If this problem is still important to you in httr2, I'd suggest filing an issue offer there 😄. Thanks for using httr!

hadley avatar Oct 31 '23 19:10 hadley