trufflefluff
trufflefluff

Reputation: 1

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()

Upvotes: 0

Views: 260

Answers (1)

dropWizard
dropWizard

Reputation: 3538

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. 

Upvotes: 0

Related Questions