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

Could not authenticate with provided credentials

Open NordineKB opened this issue 6 years ago • 16 comments

I've been using Auth2 method of getting tokens, once the generated monzo.json file was made I was using the following line of code which only works for like a day until I get the error below, has anyone had the same or know whats causing it?

oclient = MonzoOAuth2Client(client_id, client_secret).from_json() client = Monzo.from_oauth_session(oclient)

["Traceback (most recent call last): File "/home/ubuntu/.local/lib/python3.6/site-packages/monzo/auth.py", line 107, in make_request self.session.request(method, url, data=data, **kwargs)) File "/home/ubuntu/.local/lib/python3.6/site-packages/requests_oauthlib/oauth2_session.py", line 330, in request http_method=method, body=data, headers=headers) File "/home/ubuntu/.local/lib/python3.6/site-packages/oauthlib/oauth2/rfc6749/clients/base.py", line 198, in add_token raise TokenExpiredError() oauthlib.oauth2.rfc6749.errors.TokenExpiredError: (token_expired)

During handling of the above exception, another exception occurred:

Traceback (most recent call last): File "auth_test.py", line 24, in balance = client.get_balance('acc_00009U1x5f20Agu9wEFoS9') File "/home/ubuntu/.local/lib/python3.6/site-packages/monzo/monzo.py", line 132, in get_balance response = self.oauth_session.make_request(url, params=params) File "/home/ubuntu/.local/lib/python3.6/site-packages/monzo/auth.py", line 110, in make_request self.refresh_token() File "/home/ubuntu/.local/lib/python3.6/site-packages/monzo/auth.py", line 160, in refresh_token auth=HTTPBasicAuth(self.client_id, self.client_secret) File "/home/ubuntu/.local/lib/python3.6/site-packages/requests_oauthlib/oauth2_session.py", line 309, in refresh_token self.token = self._client.parse_request_body_response(r.text, scope=self.scope) File "/home/ubuntu/.local/lib/python3.6/site-packages/oauthlib/oauth2/rfc6749/clients/base.py", line 415, in parse_request_body_response self.token = parse_token_response(body, scope=scope) File "/home/ubuntu/.local/lib/python3.6/site-packages/oauthlib/oauth2/rfc6749/parameters.py", line 425, in parse_token_response validate_token_parameters(params) File "/home/ubuntu/.local/lib/python3.6/site-packages/oauthlib/oauth2/rfc6749/parameters.py", line 432, in validate_token_parameters raise_from_error(params.get('error'), params) File "/home/ubuntu/.local/lib/python3.6/site-packages/oauthlib/oauth2/rfc6749/errors.py", line 405, in raise_from_error raise cls(**kwargs) oauthlib.oauth2.rfc6749.errors.InvalidClientIdError: (invalid_request) Could not authenticate with provided credentials"](url)

NordineKB avatar Jul 31 '19 09:07 NordineKB

Which version of requests_oauthlib do you have?

adesnmi avatar Jul 31 '19 10:07 adesnmi

I downgraded it to 1.0.0

NordineKB avatar Jul 31 '19 10:07 NordineKB

Could it be this? Are you refreshing the tokens given to you?

To limit the window of opportunity for attackers in the event an access token is compromised, access tokens expire after a number of hours

Any example code snippet I can use to recreate this (please omit any sensitive data).

adesnmi avatar Jul 31 '19 10:07 adesnmi

I made a client as Confidencial with a redirect url to http://localhost/ and running it on an AWS inststance and it looks like monzo.json has a refresh token,

I generate the monzo json file first with:

auth_start_url =  MonzoOAuth2Client(client_id, client_secret).authorize_token_url() 
print(auth_start_url)

then I paste the code I get to:

code = 'CODEHERE'
MonzoOAuth2Client(client_id, client_secret).fetch_access_token(code)

which seems to work when I use this but only for a day or so

oclient = MonzoOAuth2Client(client_id, client_secret).from_json()
client = Monzo.from_oauth_session(oclient)

NordineKB avatar Jul 31 '19 11:07 NordineKB

@NordineKB that is odd. Looking at the original trace you send, it looks like there's an issue with refreshing the token. I'll look into this for you.

adesnmi avatar Jul 31 '19 11:07 adesnmi

Many thanks 👍 @muyiwaolu

NordineKB avatar Jul 31 '19 11:07 NordineKB

@NordineKB just a heads up, still looking into this. I'm going to wait a day for the expiry on a test project I have and see if I can replicate your issue.

adesnmi avatar Aug 01 '19 10:08 adesnmi

@muyiwaolu Any luck replicating it? I've created a new confidential client and I got the same issue today

NordineKB avatar Aug 02 '19 11:08 NordineKB

Any news? I got a similar problem.

streetpunkpl avatar Sep 02 '19 10:09 streetpunkpl

@streetpunkpl Hi, yes I've figured out a way around it, I'll post my fix later today

NordineKB avatar Sep 02 '19 13:09 NordineKB

@NordineKB Thanks so much. It will help me a lot.

streetpunkpl avatar Sep 02 '19 13:09 streetpunkpl

@streetpunkpl

Essentially in auth.py (https://github.com/muyiwaolu/monzo-python/blob/dev/monzo/auth.py) the way it requests tokens is wrong. I've had a look at the API documentation and it needs to be some thing like:

def refresh_token(self):
        filename=MONZO_CACHE_FILE
        token = load_token_from_file(filename)
        client_id = token.get(CLIENT_ID)
        client_secret = 'PUTYOURCLIENTSECRETHERE'
        refresh_token = token.get(REFRESH_TOKEN)

        token = self.session.refresh_token(
            MonzoOAuth2Client._refresh_token_url,
            body=urllib.parse.urlencode({'grant_type': 'refresh_token','client_id':client_id,'client_secret':client_secret,'refresh_token':refresh_token})
            )

        token.update({CLIENT_SECRET: self.client_secret})

        if self.session.token_updater:
            self.session.token_updater(token)

        return token

also I used urllib so need to add that to the top

import urllib

This is a bit hacky and I'm sure someone can write a cleaner way of fixing it without pasting in the client secret. I might make a PR if I get the time to but this code fixed it for me :)

NordineKB avatar Sep 02 '19 17:09 NordineKB

Man send me your PayPal.me link if it's working I'm gonna tip you for ☕ :P

I'm totally newbie on Python (totally don't understand oauth2 protocol) . Just playing around Monzo data, but it's quite anoying when I need refresh token every 30hours. Thanks a lot.

streetpunkpl avatar Sep 02 '19 18:09 streetpunkpl

@streetpunkpl Happy to help! let me know if it works for you

NordineKB avatar Sep 03 '19 08:09 NordineKB

@NordineKB Your fix works FLAWLESSLY! Thank you so much :))))

streetpunkpl avatar Sep 04 '19 17:09 streetpunkpl

@NordineKB awesome fix! I'll integrate it when I get a chance, although I'm quite busy so a PR would be super appreciated!

adesnmi avatar Sep 20 '19 19:09 adesnmi