EMBED-API, Google analytics, server-side authorization - python

I can't seem to get the EMBED-API Server-side Authorization demo to work:
https://ga-dev-tools.appspot.com/embed-api/server-side-authorization/
In the demo it says the following:
Once the library is installed you can add the following python module
to your project and invoke the get_access_token() method to get an
access token that you can use to authorize the Embed API.
# service-account.py
from oauth2client.service_account import ServiceAccountCredentials
# The scope for the OAuth2 request.
SCOPE = 'https://www.googleapis.com/auth/analytics.readonly'
# The location of the key file with the key data.
KEY_FILEPATH = 'path/to/json-key.json'
# Defines a method to get an access token from the ServiceAccount object.
def get_access_token():
return ServiceAccountCredentials.from_json_keyfile_name(
KEY_FILEPATH, SCOPE).get_access_token().access_token
I've succesfully done all the previous steps, but this one I just can't get my head around. Where do I put this code? It seems as if it should be put in a .py file.
Can someone please help?

It depends on your implementation, but basically you want to run your service account code on your server, and have the access token passed to your client application so it can make authorized requests from the browser.
The whole app is open sourced and you can see where the service account code is in the source code.
As in the demo, if you are using django or app engine it is easy to put python server code in your site which will return the token and replace the value in template code.

Add that code in service-account.py file and upload it on your server using FTP. I saved the code using dreamweaver, updated the path and added following line at the end of the service-account.py file:
print get_access_token()
Upload .JSON file in same directory and ran the command python service-account.py to get access_token.

Related

Spotify / Spotipy web api access token authorization problem running on Google Cloud Function

Im creating a Python script which requests user data from my Spotify account.
This is the piece of my code which gets the access token:
def access_token():
redirect_uri="http://localhost:8080"
scope = 'user-read-recently-played'
obj = spotipy.oauth2.SpotifyOAuth(client_id=CLIENT_ID,client_secret=CLIENT_SECRET,redirect_uri=redirect_uri,scope=scope)
token = obj.get_access_token(as_dict=False,check_cache=False)
return token
Locally when my redirect_uri was http://localhost the script would open a webpage and I would have to copy the url and paste it as an input back in my python script in order to acquire the access token.
screenshot of this
Im obviously trying to automate this so I changed the uri to http://localhost:8080.
This would then open the webpage but immediately close and I would have the access token returned in my script without having to paste the url.
When I run this locally this works fine but when I run it in a Google Cloud Function it times out . I get this info log:
User authentication requires interaction with your web browser. Once you enter your credentials and give authorization, you will be redirected to a url. Paste that url you were directed to to complete the authorization.
any suggestions to fix this as its not an error but it times out my function.

Authentication OneDrive API Python

Using code sample from GitHub that is specifically for setting up authentication for Python access to OneDrive API (I'm beginning to think this source is outdated), I've failed to make it past the part where you paste code provided by Microsoft after executing program..
Python code:
import onedrivesdk
redirect_uri = 'https://login.microsoftonline.com/common/oauth2/nativeclient'
client_secret = '*this code omitted*'
client_id='*this code omitted*'
api_base_url='https://api.onedrive.com/v1.0/'
scopes=['onedrive.readwrite']
http_provider = onedrivesdk.HttpProvider()
auth_provider = onedrivesdk.AuthProvider(
http_provider=http_provider,
client_id=client_id,
scopes=scopes)
client = onedrivesdk.OneDriveClient(api_base_url, auth_provider, http_provider)
auth_url = client.auth_provider.get_auth_url(redirect_uri)
# Ask for the code
print('Paste this URL into your browser, approve the app\'s access.')
print('Copy everything in the address bar after "code=", and paste it below.')
print(auth_url)
code = raw_input('Paste code here: ')
client.auth_provider.authenticate(code, redirect_uri, client_secret)
After executing code and pasting url in browser, a popup shows up, where I verify that I want to give my app access to API.. I hit "Ok."
I am then presented with code in URL taskbar. I copy and paste code into program..
Then the error I get is:
raise Exception(str(message["error"]))
Exception: invalid_request
Link to GitHub source used: https://github.com/OneDrive/onedrive-sdk-python
Note: I had to omit scopes such as the first two in this list:
scopes=['wl.signin', 'wl.offline_access', 'onedrive.readwrite']
because they apparently don't exist (according to error code provided by Microsoft after pasting URL into taskbar)
Is there a better source for setting up authentication for a Python program to communicate with OneDrive API?
I am a relatively new Python user, your patience is appreciated.
I ran into the same issue and the solution was to include the redirect_uri in the app registration.
This can be done at https://portal.azure.com/ und Azure Active Directory > App registrations > "Your App" > Authentication. In my case, I needed to add http://localhost:8080/ to the redirect URIs.
I found the suggestion here:
https://github.com/OneDrive/onedrive-sdk-python/issues/98
Hope it helps someone save some time.

python linkedin oauth2 - where is http_api.py?

I'm trying to get this example to work from https://github.com/ozgur/python-linkedin. I'm using his example. When I run this code. I don't get the RETURN_URL and authorization_code talked about in the example. I'm not sure why, I think it is because I'm not setting up the HTTP API example correctly. I can't find http_api.py, and when I visit http://localhost:8080, I get a "this site can't be reached".
from linkedin import linkedin
API_KEY = 'wFNJekVpDCJtRPFX812pQsJee-gt0zO4X5XmG6wcfSOSlLocxodAXNMbl0_hw3Vl'
API_SECRET = 'daJDa6_8UcnGMw1yuq9TjoO_PMKukXMo8vEMo7Qv5J-G3SPgrAV0FqFCd0TNjQyG'
RETURN_URL = 'http://localhost:8000'
authentication = linkedin.LinkedInAuthentication(API_KEY, API_SECRET, RETURN_URL, linkedin.PERMISSIONS.enums.values())
# Optionally one can send custom "state" value that will be returned from OAuth server
# It can be used to track your user state or something else (it's up to you)
# Be aware that this value is sent to OAuth server AS IS - make sure to encode or hash it
#authorization.state = 'your_encoded_message'
print authentication.authorization_url # open this url on your browser
application = linkedin.LinkedInApplication(authentication)
http_api.py is one of the examples provided in the package. This is an HTTP server that will handle the response from LinkedIn's OAuth end point, so you'll need to boot it up for the example to work.
As stated in the guide, you'll need to execute that example file to get the server working. Note you'll also need to supply the following environment variables: LINKEDIN_API_KEY and LINKEDIN_API_SECRET.
You can run the example file by downloading the repo and calling LINKEDIN_API_KEY=yourkey LINKEDIN_API_SECRET=yoursecret python examples/http_api.py. Note you'll need Python 3.4 for it to work.

401 Unauthorized making REST Call to Azure API App using Bearer token

I created 2 applications in my Azure directory, 1 for my API Server and one for my API client. I am using the Python ADAL Library and can successfully obtain a token using the following code:
tenant_id = "abc123-abc123-abc123"
context = adal.AuthenticationContext('https://login.microsoftonline.com/' + tenant_id)
token = context.acquire_token_with_username_password(
'https://myapiserver.azurewebsites.net/',
'myuser',
'mypassword',
'my_apiclient_client_id'
)
I then try to send a request to my API app using the following method but keep getting 'unauthorized':
at = token['accessToken']
id_token = "Bearer {0}".format(at)
response = requests.get('https://myapiserver.azurewebsites.net/', headers={"Authorization": id_token})
I am able to successfully login using myuser/mypass from the loginurl. I have also given the client app access to the server app in Azure AD.
Although the question was posted a long time ago, I'll try to provide an answer. I stumbled across the question because we had the exact same problem here. We could successfully obtain a token with the adal library but then we were not able to access the resource I obtained the token for.
To make things worse, we sat up a simple console app in .Net, used the exact same parameters, and it was working. We could also copy the token obtained through the .Net app and use it in our Python request and it worked (this one is kind of obvious, but made us confident that the problem was not related to how I assemble the request).
The source of the problem was in the end in the oauth2_client of the adal python package. When I compared the actual HTTP requests sent by the .Net and the python app, a subtle difference was that the python app sent a POST request explicitly asking for api-version=1.0.
POST https://login.microsoftonline.com/common//oauth2/token?api-version=1.0
Once I changed the following line in oauth2_client.py in the adal library, I could access my resource.
Changed
return urlparse('{}?{}'.format(self._token_endpoint, urlencode(parameters)))
in the method _create_token_url, to
return urlparse(self._token_endpoint)
We are working on a pull request to patch the library in github.
For the current release of Azure Python SDK, it support authentication with a service principal. It does not support authentication using an ADAL library yet. Maybe it will in future releases.
See https://azure-sdk-for-python.readthedocs.io/en/latest/resourcemanagement.html#authentication for details.
See also Azure Active Directory Authentication Libraries for the platforms ADAL is available on.
#Derek,
Could you set your Issue URL on Azure Portal? If I set the wrong Issue URL, I could get the same error with you. It seems that your code is right.
Base on my experience, you need add your application into Azure AD and get a client ID.(I am sure you have done this.) And then you can get the tenant ID and input into Issue URL textbox on Azure portal.
NOTE:
On old portal(manage.windowsazure.com),in the bottom command bar, click View Endpoints, and then copy the Federation Metadata Document URL and download that document or navigate to it in a browser.
Within the root EntityDescriptor element, there should be an entityID attribute of the form https://sts.windows.net/ followed by a GUID specific to your tenant (called a "tenant ID"). Copy this value - it will serve as your Issuer URL. You will configure your application to use this later.
My demo is as following:
import adal
import requests
TenantURL='https://login.microsoftonline.com/*******'
context = adal.AuthenticationContext(TenantURL)
RESOURCE = 'http://wi****.azurewebsites.net'
ClientID='****'
ClientSect='7****'
token_response = context.acquire_token_with_client_credentials(
RESOURCE,
ClientID,
ClientSect
)
access_token = token_response.get('accessToken')
print(access_token)
id_token = "Bearer {0}".format(access_token)
response = requests.get(RESOURCE, headers={"Authorization": id_token})
print(response)
Please try to modified it. Any updates, please let me know.

Cannot get authentication with google api from python script to work - Error: redirect_uri_mismatch

I am trying to create a trivial python script that allows me to bulk add a list of youtube videos to a playlist of mine.
The problem I am having is getting this script to get authenticated to the google api with my apps credentials.
I am basically just using the sample authentication script at https://developers.google.com/google-apps/calendar/quickstart/python
and this stackoverflow question (Adding youtube video to playlist using Python)
The main stopping point is that I keep getting an Error: redirect_uri_mismatch. Since I am calling the script from the commandline on my laptop, the error is saying: The redirect URI in the request: http://localhost:8080/ did not match a registered redirect URI.
I have set http://localhost:8080 as the JavaScript origins and http://localhost:8080/oauth2callback as the Redirect URIs
And i am using the following (as run from the python shell):
from oauth2client.client import flow_from_clientsecrets
from oauth2client.file import Storage
from oauth2client import tools
from oauth2client.tools import argparser, run_flow
import argparse, sys, os
flow = flow_from_clientsecrets('path to my CLIENT_SECRETS.json file', scope='https://www.googleapis.com/auth/youtube')
store = Storage('config/%s-oauth2.json' % sys.argv[0])
parser = argparse.ArgumentParser(parents=[tools.argparser])
flags = parser.parse_args()
credentials = run_flow(flow, store, flags)
then the terminal opens my browser and in the browser I get the 400 error. The following gets printed to the terminal:
Your browser has been opened to visit:
https://accounts.google.com/o/oauth2/auth?scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fyoutube&redirect_uri=http%3A%2F%2Flocalhost%3A8080%2F&response_type=code&client_id=my-CLIENT-ID&access_type=offline
If your browser is on a different machine then exit and re-run this
application with the command-line parameter
--noauth_local_webserver
I am not sure what I am really supposed to be putting as the redirect URIs and javascript origins, but I don't intend to run this anywhere else other than as a python script from the terminal of my laptop. The documentation provides https://example.com/ and https://example.com/oauth2callback as pre populated values, but clearly that's not where I am running this "app" from and I know that's just placeholder stuff.
UPDATE: not sure why, but i realize that the url the app is sending me to has the redirect_uri parameter set to just http://localhost:8080/, if i add oauth2callback to the uri than i get sent to the screen where it asks me to accept management of the youtube account. so that's odd.
UPDATE 2: and if I change my redirect uris to just http://localhost:8080/ via the developer console, i can get my credentials, but I am sure this is not the best way to be going about this.
If you are just running this through you terminal than you can use the native host by creating a client ID as an installed app and then selecting other. If you are trying to do this using the web app client ID and only want it to be local then you would use these:
JavaScript origins: http://localhost:your_port_here/
Redirect URIs: http://localhost:your_port_here/url_path
where url_path is the place you want google to send you after authentication.
Edit: the tutorial code only works if you are using a native app. If you are indeed planning to create a web app there are separate instructions.
The redirect_uri parameter set to just http://localhost:8080/ is by design. When you call tools.run_flow() it is spinning up a server of it's own behind the scenes and initiating the oauth flow. It is then expecting the redirect_uri to redirect back to the server it spun up (which is listening on port 8080) so that it can use the access_token it receives to create the credentials and put them in storage.

Categories

Resources