Oauth1 - Storing request token as access token + verification
In all the OAuth1 implementations, I've noticed that when you retrieve a request token, it's stored both as the request token and the access token when parseRequestTokenResponse() calls parseAccessTokenResponse(). Both tokens are later replaced with the real access token. I'm not sure I understand why this happens. Is it an oversight that everyone just sort of stuck with?
It creates a couple of issues, the most prominent of which shows up in every example created for these. The code will go and fetch an access token every time oauth_token is present as a $_GET variable. So that happens once and parseAccessTokenResponse() is called. This function replaces both the request and access tokens with the new access token and secret, which is how the oddity mentioned in the first paragraph manages to function.
Let's say the user refreshes for some weird reason, or presses enter or who knows what happens. They hit this same URL with the oauth_token query string. Once again, the code will try to get an access token. This time, however, it will fail, because the request token is no longer a request token - it was replaced with an access token.
How can we get around this? Instead of looking for the oauth_token query string, let's use $storage->hasAccessToken(). But this won't work either, because when the request token was fetched, it set both the request and access token and secret session variables to the request token and secret, so it would seem that the session does, in fact, have an access token, when in actuality there's only a request token. While we solved the refresh issue, the code will now just never work because it will always think there's an access token, and you'll get a friendly 401 error when you try to make an API request.
Then I had the idea to wrap an API request in a try/catch should hasAccessToken() return true, but this required some hacking as well because the Exception tossed by the Http client doesn't get caught in the request() function.
Am I thinking about something totally backward here or should something be changed here? I would propose that all service implementations stop replacing both tokens and their secrets when retrieving either so that hasAccess() does, in fact, only return true when there is a valid access token. I have a PR in for Goodreads and will see if I can make some adjustments that accomplish this. Or someone can tell me what I'm missing, which may totally be the case.
Ah, but the hasAccessToken() functions for Session and Redis are both checking for the existence of any token, not just an access token.
After I read your comment, I tried to fix this with #472 The tests themselves don't support this behaviour, but in the field the login behaviour etc. still works fine.