Google Youtube Api Access blocked: This app’s request is invalid - oauth-2.0

I am trying to access google youtube API using the auth2.0 method but am unable to get an access
token.
Given Below python code
import os
import google_auth_oauthlib.flow
import googleapiclient.discovery
import googleapiclient.errors
scopes = ["https://www.googleapis.com/auth/youtube.force-ssl"]
def main():
# Disable OAuthlib's HTTPS verification when running locally.
# *DO NOT* leave this option enabled in production.
os.environ["OAUTHLIB_INSECURE_TRANSPORT"] = "1"
api_service_name = "youtube"
api_version = "v3"
client_secrets_file = "client.json"
channel_id='channeld'
# Get credentials and create an API client
flow = google_auth_oauthlib.flow.InstalledAppFlow.from_client_secrets_file(
client_secrets_file, scopes)
credentials = flow.run_console()
youtube = googleapiclient.discovery.build(
api_service_name, api_version, credentials=credentials)
Not Sure What I am missing here ? can you help out any suggestion are welcomed

Click on the link error details. It will tell you the redirect uri your application is sending from.
Take that redirect uri and add it in google developer console, the redirect uri must exactly match.
Google OAuth2: How the fix redirect_uri_mismatch error. Part 2 server sided web applications.
web app vs installed app
The code you are using is designed for an installed application hence the oogle_auth_oauthlib.flow.InstalledAppFlow.from_client_secrets_file So to use it you need to create installed application credetials You appear to have done that. This code will open up the web browser consent screen on the machine its running on. This code is not designed for running on a web server.
update
Open your credentials.json file there should be two redirect URIs in there delete the urn:ietf:wg:oauth:2.0:oob one

Related

Authorization Error when Connecting to Youtube Analytics API with Python

I have been trying to connect during several days to the YouTube Analytics API. I see that the solution in other posts is related about selecting 'Others' in the Application Type list. Apparently, this option is not available anymore.
I have created two different OAuth 2.0 clients: Web Application and Desktop. For the first one, it is displaying the following error:
Error 400: redirect_uri_mismatch: The redirect URI in the request, urn:ietf:wg:oauth:2.0:oob, can only be used by a Client ID for native application. It is not allowed for the WEB client type.
Then, it is when I try to create a native application (Desktop App in this case), it is sending a new error message:
Error 400: invalid_request. You can't sign in to this app because it doesn't comply with Google's OAuth 2.0 policy for keeping apps secure. You can let the app developer know that this app doesn't comply with one or more Google validation rules.
I have read the Google's OAuth 2.0 policy but I am not able to understand why it doesn't comply. It's not quite specific.
Anyone that has had the same issue? This is the sample code that I have been using:
import googleapiclient.errors
import os
from googleapiclient.discovery import build
from google_auth_oauthlib.flow import InstalledAppFlow
from google.auth.transport.requests import Request
scopes = ["https://www.googleapis.com/auth/youtube.readonly"]
def main():
# Disable OAuthlib's HTTPS verification when running locally.
# *DO NOT* leave this option enabled in production.
#os.environ["OAUTHLIB_INSECURE_TRANSPORT"] = "1"
api_service_name = "youtubeAnalytics"
api_version = "v2"
client_secrets_file = "cliente_analytics.json"
# Get credentials and create an API client
flow = google_auth_oauthlib.flow.InstalledAppFlow.from_client_secrets_file(
client_secrets_file, scopes)
credentials = flow.run_console()
youtube_analytics = googleapiclient.discovery.build(
api_service_name, api_version, credentials=credentials)
request = youtube_analytics.reports().query(
dimensions="day",
endDate="2021-04-01",
ids="channel==MINE",
maxResults=5,
metrics="likes",
startDate="2021-03-01"
)
response = request.execute()
print(response)
if __name__ == "__main__":
main()
Thanks
The code you are using is designed for an installed application hence the
flow = google_auth_oauthlib.flow.InstalledAppFlow.from_client_secrets_file(
client_secrets_file, scopes)
fixing invalid_request. You can't sign in to this app because it doesn't comply with Google's OAuth 2.0 policy for keeping apps secure.
Can be a bit tricking.
Make sure the app is running https.
Check that its still set to testing in google cloud console
Make sure the name of your project in google developer console doesn't contain the world Google or any google products. For example naming your project BEST YOUTUBE app is not going to pass.

Generating Credentials Auth Error - redirect_uri

I'm receiving an Authorization error when attempting to generate an authorization code:
Error 400: invalid_request
You can't sign in to this app because it doesn't comply with Google's
OAuth 2.0 policy for keeping apps secure.
If you’re the app developer, make sure that these request details
comply with Google policies. redirect_uri: urn:ietf:wg:oauth:2.0:oob
I've used this Google tutorial to replicate and confirm the issue:
https://developers.google.com/assistant/sdk/guides/service/python/embed/install-sample?hl=en_US
It is generating this URL:
https://accounts.google.com/o/oauth2/auth?response_type=code&client_id=[HIDDEN]&redirect_uri=urn%3Aietf%3Awg%3Aoauth%3A2.0%3Aoob&scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fassistant-sdk-prototype&state=[HIDDEN]&prompt=consent&access_type=offline
Here is a workaround provided by jdtoth on Github: https://github.com/greghesp/assistant-relay/issues/266#issuecomment-1065940698
Thanks jdtoth!
I found a workaround for creating a new user. In my case, I needed to
create a specific type of API credential. Here is what I did:
Create a new OAuth Client credential using the link below, ensuring
the application type is "Web application" and set Authorized Redirect
URIs to "http://localhost"
https://console.cloud.google.com/apis/credentials
Download the key, and create the user in the Assistant Relay appas you
tried before. When it opens a new browser window to authorize the
google account, you might need to bypass a warning. After you do this,
a blank browser window will open but the address bar will contain the
auth code you need. Grab the code from the relevant part of the URL
here and paste it back into the Assistant Relay app:
http://localhost/?code=COPYCODEFROMHERE&scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fassistant-sdk-prototype
Let me know if this works. I am successfully sending commands to the
Assistant Relay server but nothing is playing on my speakers.

Why google oauth flow is failing when initiated from frontend, but seems to work if I initiate from backend directly?

I have a Flash backend using flask-dance in order to allow a web app to authenticate users with Google provider.
In my local dev environment, the backend runs from https://localhost:5000, while my local frontend is at https://local.mydomain.com
I have a backend endpoint at https://localhost:5000/login/google which redirects the user to the Google OAuth flow:
#app.route('/login/<provider>')
def login(provider: str):
# here we store the page the user has come from with the referrer value
session["return_to"] = request.referrer
if provider == 'google':
return redirect(url_for("google.login"))
return False
If I access this URL directly in the browser, I'm redirected to Google and the OAuth flow completes successfully.
If, however, I add a button on the frontend that redirects to that URL, the OAuth flow fails midway and the browser prints the following errore:
Access to XMLHttpRequest at 'https://accounts.google.com/o/oauth2/auth?response_type=code&client_id=580945975384-0mqduo9k8dchc0ho7tnd7g6ejo70jrlb.apps.googleusercontent.com&redirect_uri=https%3A%2F%2Flocalhost%3A5000%2Fauth%2Fgoogle%2Fauthorized&scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.email+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.profile+openid&state=tWt5b2pkp0jfjxtXD8aHlMwsKyuCJw' (redirected from 'https://localhost:5000/login/google') from origin 'https://local.mydomain.com' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
index.js:1 Error: Network Error
at createError (createError.js:16)
at XMLHttpRequest.handleError (xhr.js:117)
xhr.js:210 GET https://accounts.google.com/o/oauth2/auth?response_type=code&client_id=580945975384-0mqduo9k8dchc0ho7tnd7g6ejo70jrlb.apps.googleusercontent.com&redirect_uri=https%3A%2F%2Flocalhost%3A5000%2Fauth%2Fgoogle%2Fauthorized&scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.email+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.profile+openid&state=tWt5b2pkp0jfjxtXD8aHlMwsKyuCJw net::ERR_FAILED 200
This is the failed request:
The Flask backend app has CORS enabled.
Why is this happening?
I suspect that running the backend locally from a different domain has something to do with it, but I couldn't quite figure out exactly what is going on and how to fix this.
The Google OAuth URL you request (https://accounts.google.com/o/oauth2/auth) is the starting point for their authentication process - it requires a full browser - it needs to display a credentials form, consent and then to redirect the browser back to your application. That's why you cannot use XMLHttpRequest for accessing it.
Your backend CORS settings cannot help it - Google would have to enable it on their endpoint, but it still would not work for the reasons mentioned before.

Google+ SignIn Hybrid Approach IOS/Python REST Server

We are trying to incorporate the Google+ SignIn button for authentication to our IOS client and python tornado REST Server.
On the IOS client, we followed the "Enable server-side API access for your app" in https://developers.google.com/+/mobile/ios/sign-in. We set the clientID to the Google+ IOS Client and the homeServerClientID to our web server Google+ Web client id.
Then on our tornado werver, we used the python google+ client and did:
oauth_flow = flow_from_clientsecrets(GOOGLE_CLIENT_SECRET, scope='email')
oauth_flow.redirect_uri = 'postmessage'
credentials = oauth_flow.step2_exchange(code)
So the IOS client works fine, it authenticates, gets the one time token in homeServerAuthorizationCode. It sends this to the REST API and it produces an exception:
File "/usr/lib/python2.6/site-packages/oauth2client/client.py", line 1964, in step2_exchange
raise FlowExchangeError(error_msg)
FlowExchangeError: redirect_uri_mismatch
We have tried to use difference codes, double and triple checked the client ids in the clientsecrets, IOS and tornado code and they are all correct.
Any ideas?
It is likely that it's not happy with the redirect URI on the server side. 'postmessage' is absolutely right for the web flow, but for iOS try either not specifying redirect_uri at all, or using 'urn:ietf:wg:oauth:2.0:oob' (oob being "out of browser") for the redirect_uri.

How to retrieve data from YouTube Analytics API without user action?

I would to create a script launched by a cron job that periodically store data about my channel in a file. Those data are retrieved via YouTube Analytics API (not the ordinary YouTube API).
How can i achieve this result?
Are service access compatible with those API?
If this is just a once-off - for your account - running on a server/desktop that you trust, I think the best mechanism will be to:
Create an OAuth client ID for an "Installed application". Create a Google Cloud Console project, enable the API you need, register your application (under "APIs & Auth").
Go through the installed application flow once manually to grant yourself a refresh token - this will require you opening a browser and clicking through a consent screen.
Persist the refresh token.
On subsequent unattended runs, use the refresh token to get a fresh access token to make calls on your behalf.
If you are using Python - and have installed the Google API Python Client, the following code will do steps 2 - 4 for you (assuming you have already done step 1 and saved a client_secrets.json file):
import httplib2
from oauth2client.file import Storage
from oauth2client.client import flow_from_clientsecrets
from oauth2client.tools import run
from apiclient.discovery import build
storage = Storage("/path/to/saved_user_creds.dat")
credentials = storage.get()
if credentials is None or credentials.invalid:
credentials = run(flow_from_clientsecrets("/path/to/client_secrets.json", scope="https://www.googleapis.com/auth/yt-analytics.readonly"), storage)
http = credentials.authorize(httplib2.Http())
# Do your stuff - remember to pass the authenticated http object to execute methods
service = build("youtubeAnalytics", "v1")
result = service.object().method(name=value).execute(http=http)

Resources