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.