Reputation: 639
I'm trying to run the requests-OAuth2 LinkedIn example. I've been able to fix a few issues with the example being out of date but cannot seem to get the last line to run correctly.
The response object contents from running the program:
b'{"serviceErrorCode":100,"message":"Unpermitted fields present in PARAMETER: Data Processing Exception while processing fields [/access_token]","status":403}
r_liteprofile
.I've added comments to explain which changes I've made from the stock tutorial on the requests-oauthlib website.
os.environ['OAUTHLIB_INSECURE_TRANSPORT'] = '1'
from requests_oauthlib import OAuth2Session
from requests_oauthlib.compliance_fixes import linkedin_compliance_fix
# Credentials you get from registering a new application
client_id = vault.CLIENT_ID
client_secret = vault.CLIENT_SECRET
# CHANGE: Scope is necessary to avoid permission errors
scope = ['r_liteprofile', 'r_emailaddress', 'w_member_social']
redirect_url = 'http://127.0.0.1'
# OAuth endpoints given in the LinkedIn API documentation (you can check for the latest updates)
# CHANGE: updated urls
authorization_base_url = 'https://www.linkedin.com/oauth/v2/authorization'
token_url = 'https://www.linkedin.com/oauth/v2/accessToken'
# Authorized Redirect URL (from LinkedIn configuration)
# CHANGE: added scope argument to OAuth2Session init method
linkedin = OAuth2Session(client_id, redirect_uri=redirect_url, scope=scope)
linkedin = linkedin_compliance_fix(linkedin)
# Redirect user to LinkedIn for authorization
authorization_url, state = linkedin.authorization_url(authorization_base_url)
print('Please go here and authorize,', authorization_url)
# Get the authorization verifier code from the callback url
redirect_response = input('Paste the full redirect URL here:')
# Fetch the access token
# CHANGED: LinkedIn required client_id to be in body, flipped include_client_id to True
linkedin.fetch_token(token_url,client_secret=client_secret,
include_client_id=True,authorization_response=redirect_response)
# CHANGED: Just an example of a header I tried passing to the get method below
headers = {'X-Restli-Protocol-Version': '2.0.0'}
r = linkedin.get('https://api.linkedin.com/v2/me')
print(r.content)
Upvotes: 1
Views: 380
Reputation: 639
As per the documentation and comments made on the github repository, https://github.com/requests/requests-oauthlib LinkedIn compliance fixes were outdated and causing bugs. The maintainers have since removed the LinkedIn compliance fix code and applied several updates to the LinkedIn example as part of PR #397. This should not be an issue anymore.
Ultimately the request url I was passing contained an unpermitted field. Manual review of the url revealed two fields:
oauth2_access_token
access_token
Looking at the OAuth2-Requests source code, the second field is added to the url right before making the final request.
requests-oauthlib/requests_oauthlib/oauth2_session.py
I imagine there is a mechanism in place to prevent the behavior but I could not find it and my comments/questions on their github and other places went unanswered. My solution was to copy a modified version of the oauth2_session.py
module in my project with this dirty fix within the request()
method.
old_version_url = url
url, headers, data = self._client.add_token(url, http_method=method, body=data, headers=headers)
# Dirty work around to prevent the `access_token` parameter from being added
# to the url, causing a unpermitted parameters error requesting linkedin resource.
if "&access_token=" in url:
url = old_version_url
The entire modified module can be found in this github repo, linkedin_assist/linkedin_assist/quick_fixes/oauth2_session.py
Upvotes: 1