I am trying to write a simple (hah!) Python Flask app which will use Google’s people
API to retrieve a user’s numeric Google ID (which otherwise seems to be almost impossible to determine). Doing this requires that the user authenticate with Google’s OAUTH. I have this working, but Google’s Using OAuth 2.0 for Web Server Applications documentation says:
The OAuth client must prevent CSRF as called out in the OAuth2
Specification . One way to achieve this is by using the state
parameter to maintain state between your authorization request and the
authorization server’s response.
So I’m following this example, and storing the state in a session variable.
@app.route('/auth')
def auth():
auth_url, state = get_oauth_flow().authorization_url()
app.logger.debug(f'Setting session state: {state}')
flask.session['state'] = state
return flask.redirect(auth_url)
@app.route('/oauth2callback')
def oauth2callback():
session_state = flask.session.get('state')
request_state = flask.request.args.get('state')
app.logger.debug(f'Got session state: {session_state}')
app.logger.debug(f'Got request state: {request_state}')
if session_state is None or session_state != request_state:
return 'Danger, Will Robinson!', 400
del flask.session['state']
flow = get_oauth_flow()
flow.fetch_token(authorization_response=flask.request.url)
flask.session['oauth_token'] = flow.credentials.token
return flask.redirect('success')
This is failing whenever I go through the initial login process. (I receive a “Danger, Will Robinson!” message.) My logs show that the session variable has been cleared.
DEBUG in ging: Setting session state: ijV2BAyuZG8uSO4rpN77nczw5UDEJf
DEBUG in ging: Got session state: None
DEBUG in ging: Got request state: ijV2BAyuZG8uSO4rpN77nczw5UDEJf
I’m not a web developer by trade, so I’m very much at sea here. Any suggestions on what I might be doing wrong and/or other approaches would be appreciated.