Problem with oAuth
Hi,
I'm having a bit of an issue getting oAuth working with the lib. I found that .get_authentication_url() doesn't exist in the ouath_client.
auth_start_url = oauth_client.get_authentication_url()
I've tried with the following, which works: sends and email and then hits the webhook in my application with the code. However I then have an issue with the following returning an exception.
oauth_client.fetch_access_token(myOauthCode)
Exception:
oauthlib.oauth2.rfc6749.errors.MissingTokenError: (missing_token) Missing access token parameter.
Not sure if i'm missing something? Any help is much appreciated.
Ryan
Hey, sorry about this. Looks like when writing the README I flubbed authorize_token_url into get_authentication_url. I'll get that fixed.
You should use this method before fetch_access_token although based on you getting an email I'm guessing you worked this out?
I find that error quite odd. Have you checked that your application is correctly extracting the authentication token from the webhook?
Hi Tom,
Thanks for getting back to me.
The webhook at the minute is saving the 'code' request argument/query string to a variable, and then using that variable in the fetch_access_token function. Is this correct?
Many thanks
Yep, that's right.
I don't think I can really help much without being able to see your code.
Sorry for the delay Tom, please find code snippets below. I'm using Flask as the webframe work which is handling the callback url and extracting the code.
Class for my monzo functons:
includes.api.monAPI
Function to generate URL:
def oauthStart(self):
self.oauthClient = MonzoOAuth2Client(self.clientID , self.clientSecret, redirect_uri=self.redirectURL)
auth_start_url = self.oauthClient.authorize_token_url(self.redirectURL)
return auth_start_url
Output:
('https://auth.monzo.com?response_type=code&client_id=oauth2client_xxxxxxx&redirect_uri=https%3A%2F%2Fxxxxxxx%3A8443%2Fapi%2Fmonzo%2Fcallback&state=xxxxxxxxxxx', 'xxxxxxxxxx')
Function for callback:
@app.route('/api/monzo/callback', methods=['GET'])
def monzo_oauth():
if not request.args.get("code", None) == None:
logger.debug(request.args)
includes.api.monAPI.oauthCode = request.args["code"]
includes.api.monAPI.oauthGetToken()
logger.info("Monzo oauth code updated")
return jsonify(), 200
logger.debug(request.args)
return abort(400)
Function triggered by the callback:
def oauthGetToken(self):
data = self.oauthClient.fetch_access_token(self.oauthCode)
logger.debug(data)
return data
Please let me know if you need anything else to assist. Much appreciated. Best, Ryan
Hey Ryan,
Yup that looks good. The issue is on our end.
It looks like requests_oauthlib have made a breaking change and we haven't locked the version we use. We'll get a fix pushed but in the meantime you can manually make sure you have requests_oauthlib==1.0.0 rather than requests_oauthlib==1.2.0
Thanks Tom,
I've downgraded the module and it's working fine now.
Many thanks, Ryan
Good to hear. :)
No problem. Thanks for bringing this up, this is something you only really see if you're doing a fresh install.
This issue still exists even with the libraries explicitly set
Can you post the full traceback of the exception? @maitham1
I'm seeing the same error, looks like it is a result of a Monzo API change where this package is trying to send client_id and client_secret as username and password respectively when exchanging an auth code for an access token. A small update to the fetch_access_token method fixes this:
def fetch_access_token(self, code, redirect_uri=None):
"""Step 2: Given the code from Monzo from step 1, call
Monzo again and returns an access token object. Extract the needed
information from that and save it to use in future API calls.
the token is internally saved
:rtype: A Dictionary representation of the authentication status.
"""
if redirect_uri:
self.session.redirect_uri = redirect_uri
token = self.session.fetch_token(
MonzoOAuth2Client._access_token_url,
- username=self.client_id,
- password=self.client_secret,
+ include_client_id=True,
+ client_secret=self.client_secret,
code=code,
)
if self.session.token_updater:
self.session.token_updater(token)