Mendeley / mendeley-api-python-catalog-example

This is a simple example of an application that consumes the Mendeley API, using the Python SDK.
Apache License 2.0
23 stars 6 forks source link

Missing access token parameter error #4

Open rg2410 opened 8 years ago

rg2410 commented 8 years ago

Hi,

I'm using python 2.7 and the config file method with the packages used in the requirements file. I'm coming across the following error:

File "mendeley-catalog.py", line 23, in session = mendeley.start_client_credentials_flow().authenticate() File "/home/rafael/anaconda2/envs/mendeley/lib/python2.7/site-packages/mendeley/auth.py", line 31, in authenticate token = oauth.fetch_token(self.token_url, auth=self.auth, scope=['all']) File "/home/rafael/anaconda2/envs/mendeley/lib/python2.7/site-packages/requests_oauthlib/oauth2_session.py", line 199, in fetch_token self._client.parse_request_body_response(r.text, scope=self.scope) File "/home/rafael/anaconda2/envs/mendeley/lib/python2.7/site-packages/oauthlib/oauth2/rfc6749/clients/base.py", line 409, in parse_request_body_response self.token = parse_token_response(body, scope=scope) File "/home/rafael/anaconda2/envs/mendeley/lib/python2.7/site-packages/oauthlib/oauth2/rfc6749/parameters.py", line 376, in parse_token_response validate_token_parameters(params) File "/home/rafael/anaconda2/envs/mendeley/lib/python2.7/site-packages/oauthlib/oauth2/rfc6749/parameters.py", line 386, in validate_token_parameters raise MissingTokenError(description="Missing access token parameter.") oauthlib.oauth2.rfc6749.errors.MissingTokenError: (missing_token) Missing access token parameter.

Could you please advise on how to solve this? Thank you.

JimHokanson commented 8 years ago

@rg2410

If you open the fetch_token method in "requests_oauthlib/oauth2_session.py" and look at the response to the post, what does it say?

In my case I have a line in the code like:

r = self.post(token_url, data=dict(urldecode(body)), timeout=timeout, headers=headers, auth=auth, verify=verify)

Around like 220 ish (I edited the file so my line number may be off)

What are the rough values/formats of: r.text - value? auth.username - rough format? auth.password - rough format?

For the username and password do you have something like: print(auth.username) => 255 print(auth.password) => 'asdfasdfasdfasdfasdfasdfsadf'

eenblam commented 8 years ago

@JimHokanson

I'm having the same issue. From the Werkzeug debugger:

r.text is a 401 with u'{"message":"Credentials are required to access this resource."}' print(auth.username => My Mendeley application id print(auth.password) => My Mendeley client secret

JimHokanson commented 8 years ago

@eenblam

That's strange. This is basically the first request being made. That is the same message I get when I create a fake username, indicating that this error message (from Mendeley) is not very specific.

I do remember that when I was creating a test account I had difficulty using the API until I had verified my account. Perhaps that is an issue.

Perhaps it is something weird about your Python setup. I was able to use the website Hurl.it to make a post request with the following:

POST https://api.mendeley.com/oauth/token Basic authentication with user name and password 'Accept': 'application/json', 'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8', Body => grant_type=client_credentials&scope=all

At first this failed with 406 but I closed the site and opened it again and it worked (whitespace copying issue?)

eenblam commented 8 years ago

@JimHokanson Thanks for the prompt reply!

I just noticed I commented on the wrong issue. My setup is from mendeley-api-python-example. Moving.

JimHokanson commented 8 years ago

@eenblam

Can you run a curl command and see if this works. I haven't tried it yet so I can't verify that it works. The instructions for hurl.it did work for me though ...

Make sure to change the username and password values e.g. -u 123:asdfadfadfasdfasdfasdf

curl -u username:password -XPOST -H 'Content-Type: application/x-www-form-urlencoded;charset=UTF-8' -H 'Accept: application/json' -d 'grant_type=client_credentials&scope=all' 'https://api.mendeley.com/oauth/token'

The other thing that stands out is that the version of requests is really old. Perhaps there was a system specific bug in one of the older versions. You might try upgrading that ...

eenblam commented 8 years ago

@JimHokanson

curl returned 401 with same message as before. Registered a new app just to be certain I hadn't mis-recorded the secret key. Also, thanks for the help.

JimHokanson commented 8 years ago

@eenblam

Good to know. I haven't verified that command yet so my command could be bad. I'll let you know when I try it.

eenblam commented 8 years ago

@JimHokanson I'm planning to continue looking into it further on Saturday, but I'd love to hear whatever you find in the meantime! Thanks.

JimHokanson commented 8 years ago

@eenblam

I confirmed that on my mac the above command works after changing the -u username:password bit to something like -u 123:asdfasdfasdfadsfasdfasdf

My best guess at this point is that you need to login to the Mendeley website with the account you used to register your app. I seem to remember seeing some sort of popup when I logged in that officially activated my account.

@MendeleyStack Can you confirm that there is some sort of activation procedure, without which API calls won't work. Also, can the error message be cleaned up to distinguish between an account that requires activation, an invalid authentication parameter (bad user/pass combo) and the current error message which seems to suggest that no credentials were provided? The Python code would need to be updated since the 'oathlib' package isn't passing on the error. Presumably this could be fixed relatively easy by a patch to that package that shows the error from the server to the user rather than current error message: "Missing access token parameter"

eenblam commented 8 years ago

@JimHokanson I tried again this morning - without changing anything on my end - and it worked. Magic.

EDIT: That is, authenticating via the SDK succeeded. I first tried entering an incorrect password as a sanity check (it failed and asked me to resubmit,) and my subsequent attempt with the correct password succeeded.

The above curl still returns the "Credentials are required..." response.

eenblam commented 8 years ago

@JimHokanson @MendeleyStack

I think oauthlib already supports the behavior you want, if you're willing to update your response from a message to an error.

fetch_token will call parse_token_response, which will call validate_token_parameters just before returning. See validate_token_parameters in the oauthlib source. This function will raise an appropriate error if it finds an 'error' in the response. Excerpt:

def validate_token_parameters(params):
    """Ensures token precence, token type, expiration and scope in params."""
    if 'error' in params:
        raise_from_error(params.get('error'), params)
    ...

raise_from_error is here.

Joyce-Stack commented 8 years ago

@MendeleyStack Can you confirm that there is some sort of activation procedure, without which API calls won't work. Also, can the error message be cleaned up to distinguish between an account that requires activation, an invalid authentication parameter (bad user/pass combo) and the current error message which seems to suggest that no credentials were provided? The Python code would need to be updated since the 'oathlib' package isn't passing on the error. Presumably this could be fixed relatively easy by a patch to that package that shows the error from the server to the user rather than current error message: "Missing access token parameter"

@JimHokanson There is a step verification step for your email but I've been told that it has nothing to do with authorisation and so should not impact this. Its more a marketing thing. Do you want me to update the 'oauthlib' library to the next version? I'm happy for you to create a pull request as my python is not all that great.

I have successfully been able to run the query below and receive back an access token response.
Steps I took:

  1. created a new account with a new email address on Mendeley but I did not sign into mendeley.com or verified my account
  2. I signed in via the developer portal to register an application and get a new secret which I used below

curl -u CLIENT_ID:CLIENT_SECRET -XPOST -H 'Content-Type: application/x-www-form-urlencoded;charset=UTF-8' -H 'Accept: application/json' -d 'grant_type=client_credentials&scope=all' 'https://api.mendeley.com/oauth/token'

I received back an access token response

{"access_token":"ACCESS_TOKEN","token_type":"bearer","expires_in":3600,"refresh_token":null....}

notbanker commented 5 years ago

Is this still maintained? I'm getting a missing access token parameter when I try the following minimalist example:

mendeley = Mendeley(client_id=config['clientId'], client_secret=config['clientSecret'])
session = mendeley.start_client_credentials_flow().authenticate()
dreamflasher commented 4 years ago

@notbanker No updates for a couple of years, I doubt it.

But your authenticate is missing the full url. auth.authenticate("http://localhost:8888/tree?code=yS9T_0E1XCNAeA7FtX-AwR4yo&state=UK5X4AE6WI0V7L7IP8R3JVG6O3BT")

I got the same error as mentioned here and that solved the problem for me. Also after start_client_credentials_flow you need to perform the credentials flow – login to mendeley. And get the above url.