monzo-python icon indicating copy to clipboard operation
monzo-python copied to clipboard

Problem with oAuth

Open rlaunch opened this issue 7 years ago • 10 comments

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

rlaunch avatar Feb 05 '19 08:02 rlaunch

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?

TomAFrench avatar Feb 05 '19 10:02 TomAFrench

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

rlaunch avatar Feb 05 '19 19:02 rlaunch

Yep, that's right.

I don't think I can really help much without being able to see your code.

TomAFrench avatar Feb 05 '19 19:02 TomAFrench

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

rlaunch avatar Feb 09 '19 10:02 rlaunch

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

TomAFrench avatar Feb 10 '19 21:02 TomAFrench

Thanks Tom,

I've downgraded the module and it's working fine now.

Many thanks, Ryan

rlaunch avatar Feb 10 '19 22:02 rlaunch

Good to hear. :)

No problem. Thanks for bringing this up, this is something you only really see if you're doing a fresh install.

TomAFrench avatar Feb 10 '19 23:02 TomAFrench

This issue still exists even with the libraries explicitly set

maitham avatar Jun 27 '19 21:06 maitham

Can you post the full traceback of the exception? @maitham1

ghost avatar Jun 27 '19 21:06 ghost

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)

robwatkiss avatar Sep 11 '19 15:09 robwatkiss