Facebook API Auth 2 with python or Django - python

I am trying ti get user Token using Facebook oauth2 api but i am facing this error when redirect url call.
InsecureTransportError at /data/FacebookAuth/
(insecure_transport) OAuth 2 MUST utilize https.
I have running ngrok & https setup but i can't figure out why it is giving me this error
Here is my code to get this token in django
#Facebook App Credentials
client_id = 'xxxx'
client_secret = 'xxxxx'
# OAuth endpoints given in the Facebook API documentation>
authorization_base_url = 'https://www.facebook.com/dialog/oauth'
token_url = 'https://graph.facebook.com/oauth/access_token'
redirect_uri = 'https://ab207c1f.ngrok.io/data/FacebookAuthRedirect'
facebook = OAuth2Session(client_id, redirect_uri=redirect_uri)
facebook = facebook_compliance_fix(facebook)
#Getting Facebook Authentication
def FacebookAuth(request):
authorization_url, state = facebook.authorization_url(authorization_base_url)
redirect(authorization_url)
#Getting Facebook Authentication Redirect
def FacebookAuthRedirect(request):
redirect_response = request.GET.get('code', '')
token = facebook.fetch_token(token_url, client_secret=client_secret,
authorization_response=redirect_response)
print(token)
return HttpResponse('ibrahim')

After digging a bit. I found a solution that worked for me.
it was because of authorization_code = request.build_absolute_uri(). I tried printing it and it contained "http" instead of "https". I replaced the string with https using the following code.
redirect_response = redirect_response.replace("http://", "https://")

Related

Python - "client_id" is missing. How to solve?

I've been playing with the LinkedIn api (OAuth 2) and I've found an example to help test it. I've followed the tutorial to the letter, but for some reason when I provide my full redirect URL (as requested in the code), I get the error: (invalid_request) A required parameter "client_id" is missing. I'm not sure what I'm doing wrong, but if anyone has any idea, I appreciate the feedback.
Upon searching for a solution, I've found another person struggling with this: "client_id" is missing when authenticate with LinkedIn
Here's the code from the example:
Linkedin.py
from requests_oauthlib import OAuth2Session
from requests_oauthlib.compliance_fixes import linkedin_compliance_fix
# Credentials you get from registering a new application
client_id = SECRET
client_secret = SECRET
# OAuth endpoints given in the LinkedIn API documentation
authorization_base_url = 'https://www.linkedin.com/uas/oauth2/authorization'
token_url = 'https://www.linkedin.com/uas/oauth2/accessToken'
linkedin = OAuth2Session(client_id, redirect_uri='http://localhost:8000')
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
linkedin.fetch_token(token_url, client_secret=client_secret,authorization_response=redirect_response)
# Fetch a protected resource, i.e. user profile
r = linkedin.get('https://api.linkedin.com/v1/people/~')
print (r.content)
Link to example: https://requests-oauthlib.readthedocs.io/en/latest/examples/linkedin.html
Additional Note: The tutorial I used didn't have a date on it. I can only assume the links used in the API tutorial are correct and up to date.
This one is a little old but I thought I'd share some additional changes that need to be made to the LinkedIn example from the oauth requests documentation site.
Along with the updated links, it would seem that LinkedIn is expecting the client_id in the body of the request when trading the verifier code for a a token. I'm not exactly sure where or when it gets left behind but after drilling down in oauth-request source code I found that the fetch method has an argument which forces the client_id to be included in the request body (include_client_id) adding it to the fetch method should make the example work.
linkedin.fetch_token(token_url, client_secret=client_secret,
authorization_response=redirect_response,
include_client_id=True)
The issue is with the URLs, I wrote a similar program and it worked perfectly for me:
from requests_oauthlib import OAuth2Session
from requests_oauthlib.compliance_fixes import linkedin_compliance_fix
# Credentials you get from registering a new application
client_id = '<the client id you get from linkedin>'
client_secret = '<the client secret you get from linkedin>'
redirect_url = '<authorized redirect URL from LinkedIn config>'
# OAuth endpoints given in the LinkedIn API documentation (you can check for the latest updates)
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)
linkedin = OAuth2Session(client_id, redirect_uri=redirect_url)
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
linkedin.fetch_token(token_url, client_secret=client_secret,
authorization_response=redirect_response)
# Fetch a protected resource, i.e. user profile
r = linkedin.get('https://api.linkedin.com/v1/people/~')
print(r.content)
I hope it helps!
While this may not be the reason for your issue, you are using an older version of LinkedIn's authentication URLs. From LinkedIn's OAuth documentation (https://learn.microsoft.com/en-us/linkedin/shared/authentication/authorization-code-flow?context=linkedin/consumer/context) your authorziation_base_url should be
https://www.linkedin.com/oauth/v2/authorization

OAuth2 authorization for API in Python

I'm trying to use OAuth2 authorization for an API through the company Manheim using Python 3.
The documentation states "The 'Client Credentials' and 'Resource Owner' grant types are both supported now and required changes to request a token are detailed here." Here is the documentation to the API: http://developer.manheim.com/#/authentication
I've used the following link as a guide but to no avail:
https://requests-oauthlib.readthedocs.io/en/latest/oauth2_workflow.html#backend-application-flow
They've provided me with a client id and client secret. I'm receiving the following error:
MissingTokenError: (missing_token) Missing access token parameter.
I've tried this:
from oauthlib.oauth2 import BackendApplicationClient
client_id = 'my_id'
client_secret = 'my_secret'
token_url = 'https://sandbox.api.manheim.com/oauth2/token.oauth2'
client = BackendApplicationClient(client_id=client_id)
oauth = OAuth2Session(client=client)
token = oauth.fetch_token(token_url=token_url,
client_id=client_id,client_secret=client_secret)
I've also tried this:
from oauthlib.oauth2 import BackendApplicationClient
from requests.auth import HTTPBasicAuth
client_id = 'my_id'
client_secret = 'my_secret'
token_url = 'https://sandbox.api.manheim.com/oauth2/token.oauth2'
auth = HTTPBasicAuth(client_id, client_secret)
client = BackendApplicationClient(client_id=client_id)
oauth = OAuth2Session(client=client)
token = oauth.fetch_token(token_url=token_url, auth=auth)
I've tried other techniques but have had no success. What am I doing wrong? What do I need to do access the API?
I appreciate any and all help!
RESULT:
Fixed it myself by reaching out to the developer team managing the API. I was using the wrong endpoint.
I changed token_url to the following:
token_url = 'https://api.manheim.com/oauth2/token.oauth2'

Flask session won't allow assignment from urlfetch content - Internal Server Error

I have a Python app running on Google App Engine. I am trying to perform an Oauth 2 authentication without using oauth libraries.
I need a session to store the information returned from the Google auth code (access token) and send it to the next request. When I try to store the JSON into a flask session key, my app goes to an Internal Server Error with no debug info. My code is practically a copy-paste from Google's HTTP Rest example in their Oauth2 for web server apps documentation (link commented in code).
import logging
import flask
from flask import render_template, session
import json
import urllib
from google.appengine.api import urlfetch
#Code from https://developers.google.com/identity/protocols/OAuth2WebServer
app = flask.Flask(__name__)
CLIENT_ID = '[].apps.googleusercontent.com'
CLIENT_SECRET = '[]'
SCOPE = 'email'
REDIRECT_URI = 'https://[].appspot.com/oauthcallback'
#check for last oauth step, if not go to intermediate steps
#app.route('/')
def index():
if 'credentials' not in flask.session:
return flask.render_template('index.html')
credentials = json.loads(flask.session['credentials'])
if credentials['expires_in'] <= 0:
return flask.redirect(flask.url_for('oauthcallback'))
else:
headers = {'Authorization': 'Bearer {}'.format(credentials['access_token'])}
req_uri = 'https://www.googleapis.com/oauth2/v2/userinfo'
r = requests.get(req_uri, headers=headers)
return r.text
#ask user to sign in, send code to googleapi to get token
#app.route('/oauthcallback')
def oauthcallback():
if 'code' not in flask.request.args:
auth_uri = ('https://accounts.google.com/o/oauth2/v2/auth?response_type=code&client_id={}&redirect_uri={}&scope={}').format(CLIENT_ID, REDIRECT_URI, SCOPE)
return flask.redirect(auth_uri)
else:
auth_code = flask.request.args.get('code')
data = {'code': auth_code, 'client_id': CLIENT_ID, 'client_secret': CLIENT_SECRET, 'redirect_uri': REDIRECT_URI, 'grant_type': 'authorization_code'}
r = urlfetch.fetch("https://www.googleapis.com/oauth2/v4/token", payload=data, method="POST")
#return r.content #prints json
flask.session['credentials'] = r.content #breaks here
return flask.redirect(flask.url_for('index'))
if __name__ == '__main__':
import uuid
app.secret_key = str(uuid.uuid4())
app.debug = True
app.run()
Did you enable the redirect URI?
https://developers.google.com/api-client-library/python/auth/web-app
Create authorization credentials
Any application that uses OAuth 2.0 to access Google APIs must have authorization credentials that identify the application to Google's OAuth 2.0 server. The following steps explain how to create credentials for your project. Your applications can then use the credentials to access APIs that you have enabled for that project.
Open the Credentials page in the API Console.
Click Create credentials > OAuth client ID.
Complete the form. Set the application type to Web application. Applications that use languages and frameworks like PHP, Java, Python, Ruby, and .NET must specify authorized redirect URIs. The redirect URIs are the endpoints to which the OAuth 2.0 server can send responses.
For testing, you can specify URIs that refer to the local machine, such as http://localhost:8080. With that in mind, please note that all of the examples in this document use http://localhost:8080 as the redirect URI.

Azure Active Directory get token request http error

I'm using Active Directory Authentication library for python following the documentation. Earlier on I managed to get the access_token through the Acquire Token with Client Credentials sample:
import adal
RESOURCE_URI = 'https://<mydomain>.crm.dynamics.com'
AUTHORITY_URL = "https://login.microsoftonline.com/<tenant_id>"
CLIENT_ID = 'xxxx' #application_id
CLIENT_SECRET = 'xxxx'
context = adal.AuthenticationContext(AUTHORITY_URL)
token = context.acquire_token_with_client_credentials(
RESOURCE_URI,
CLIENT_ID,
CLIENT_SECRET)
print token
But I get an error message when I tried the Acquire token and Refresh token sample
context = adal.AuthenticationContext(AUTHORITY_URL)
token = context.acquire_token_with_username_password(
RESOURCE_URI,
USERNAME,
PASSWORD,
CLIENT_ID)
print token
>>> adal.adal_error.AdalError: Get Token request returned http error: 401 and server response: {"error":"invalid_client","error_description":"AADSTS70002: The request body must contain the following parameter: 'client_secret or client_assertion'.........."correlation_id"......}
adal.adal_error.AdalError: Get Token request returned http error: 401 and server response: {"error":"invalid_client","error_description":"AADSTS70002: The request body must contain the following parameter: 'client_secret or client_assertion'.........."correlation_id"......}
There are two kinds of app we can register on Azure, native or web app. Based on the error message, it seems that you have register a confident app which requires provide its client secret to acquire the access token.
For this issue please register a native app instead of web app. Also the resource owner password credentials flow should be consider used carefully since this may leak the credentials. Refer the flows from link below:
The OAuth 2.0 Authorization Framework - Authorization Grant
I suffered from the same error.
In app registration section in azure active directory I registered the app as web host/api.
When I changed it to native app everything started to work fine.

google oauth how to get the "code" from step2 url

I am trying to authenticate using Google OAuth but am having a little trouble following the tutorial.
Here is my current setup:
FLOW = OAuth2WebServerFlow(
client_id='67490467925.apps.googleusercontent.com',
client_secret='K1tkrPK97B2W16ZGY',
scope='https://www.googleapis.com/auth/calendar',
user_agent='Real_Hub/1.0',
redirect_uri='http://127.0.0.1:8000/',)
storage = Storage('calendar.dat')
credentials = storage.get()
if credentials is None or credentials.invalid == True:
auth_uri = FLOW.step1_get_authorize_url()
return auth_uri
else:
http = httplib2.Http()
http = credentials.authorize(http)
service = build(serviceName='calendar', version='v3', http=http,
developerKey='AIzaSyCBGjIQ2uNbThW_2oMO9P-Ufb8kc')
return service
#End OAUTH...
I am unsure where I should put credentials = flow.step2_exchange(code) and storage.put(credentials) and how do I get the "code" variable? In the API it says from the redirect url. But I do not follow how to do this.
You need to define a method for handling callbacks from the OAuth provider, then map that callback method to a url on your application, something like
http://yourserver/auth_callback
Then set the redirect_uri to the auth_callback url when you create the Flow class
FLOW = OAuth2WebServerFlow(
client_id='67490467925.apps.googleusercontent.com',
...
redirect_uri='http://yourserver/auth_callback')
After you get the auth_uri, you need to redirect the user to that uri so they can authenticate/authorize
self.redirect(auth_uri, ...)
After authentication/authorization, OAuth provider will "call you back" to the redirect_uri you specified earlier. In your callback handler method, you will now parse for code or if it's not present, check for error parameter
code = self.request.get("code")
credentials = FLOW.step2_exchange(code)
NOTE: I haven't tested this, and I haven't worked with python in awhile so syntax may be off, but hopefully you get the general idea.

Categories

Resources