ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
I am writing a Web App in Flask, and I have a template index.html which checks if a user is not signed in. If not a sign in button is displayed.
Code:
<!DOCTYPE html>
<!--
To change this license header, choose License Headers in Project Properties.
To change this template file, choose Tools | Templates
and open the template in the editor.
-->
<html>
<head>
<title>Item catalog Application</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js">
</script>
<script src="//apis.google.com/js/platform.js?onload=start">
</script>
</head>
<body>
<div>TODO write content</div>
{% if not username in log_session %}
<div id="signInButton">
<span class="g-signin"
data-scope="openid email"
data-clientid="609704772765-ip5d9e502amk9r0u8rh9t3q18qdmoos8.apps.googleusercontent.com"
data-redirecturi="postmessage"
data-accesstype="offline"
data-cookiepolicy="single_host_origin"
data-callback="signInCallback"
data-approvalprompt="force">
</span>
</div>
{% else %}
<a href="/gdisconnect">Logout</a>
{% endif %}
</body>
</html>
My application.py is the following:
Code:
from flask import Flask, render_template, request, redirect, jsonify, url_for, flash
from flask import session as login_session
import random
import string
# IMPORTS FOR THIS STEP
from oauth2client.client import flow_from_clientsecrets
from oauth2client.client import FlowExchangeError
import httplib2
import json
from flask import make_response
import requests
app = Flask(__name__)
CLIENT_ID = json.loads(
open('client_secrets.json', 'r').read())['web']['client_id']
APPLICATION_NAME = "Item Catalog Application"
data = {"Snowboarding":[{"title":"Snowboard", "description":"A snowboard for skying"}, {"title":"Jacket", "description":"Waterproof jacket"}],
"Basketball":[{"title":"Basket ball", "description":"A basket ball"}, {"title":"shoes", "desctiption":"Basketball shoes"}],
"Soccer":[{"title":"Soccer ball", "description":"A soccer ball"}, {"title":"shoes", "desctiption":"Soccer shoes"}],
}
@app.route('/')
@app.route('/index')
def hello_world():
return render_template('index.html');
@app.route('/catalog.json')
def getJSON():
return str(data)
@app.route('/gconnect', methods=['POST'])
def gconnect():
state = ''.join(random.choice(string.ascii_uppercase + string.digits)
for x in range(32))
login_session['state'] = state
# Validate state token
if request.args.get('state') != login_session['state']:
response = make_response(json.dumps('Invalid state parameter.'), 401)
response.headers['Content-Type'] = 'application/json'
return response
# Obtain authorization code
code = request.data
try:
# Upgrade the authorization code into a credentials object
oauth_flow = flow_from_clientsecrets('client_secrets.json', scope='')
oauth_flow.redirect_uri = 'postmessage'
credentials = oauth_flow.step2_exchange(code)
except FlowExchangeError:
response = make_response(
json.dumps('Failed to upgrade the authorization code.'), 401)
response.headers['Content-Type'] = 'application/json'
return response
# Check that the access token is valid.
access_token = credentials.access_token
url = ('https://www.googleapis.com/oauth2/v1/tokeninfo?access_token=%s'
% access_token)
h = httplib2.Http()
result = json.loads(h.request(url, 'GET')[1])
# If there was an error in the access token info, abort.
if result.get('error') is not None:
response = make_response(json.dumps(result.get('error')), 500)
response.headers['Content-Type'] = 'application/json'
return response
# Verify that the access token is used for the intended user.
gplus_id = credentials.id_token['sub']
if result['user_id'] != gplus_id:
response = make_response(
json.dumps("Token's user ID doesn't match given user ID."), 401)
response.headers['Content-Type'] = 'application/json'
return response
# Verify that the access token is valid for this app.
if result['issued_to'] != CLIENT_ID:
response = make_response(
json.dumps("Token's client ID does not match app's."), 401)
print("Token's client ID does not match app's.")
response.headers['Content-Type'] = 'application/json'
return response
stored_credentials = login_session.get('credentials')
stored_gplus_id = login_session.get('gplus_id')
if stored_credentials is not None and gplus_id == stored_gplus_id:
response = make_response(json.dumps('Current user is already connected.'),
200)
response.headers['Content-Type'] = 'application/json'
return response
# Store the access token in the session for later use.
login_session['credentials'] = credentials
login_session['gplus_id'] = gplus_id
# Get user info
userinfo_url = "https://www.googleapis.com/oauth2/v1/userinfo"
params = {'access_token': credentials.access_token, 'alt': 'json'}
answer = requests.get(userinfo_url, params=params)
data = answer.json()
login_session['username'] = data['name']
login_session['picture'] = data['picture']
login_session['email'] = data['email']
return redirect(url_for('index.html'))
@app.route('/gdisconnect')
def gdisconnect():
access_token = login_session['access_token']
print
'In gdisconnect access token is %s', access_token
print
'User name is: '
print
login_session['username']
if access_token is None:
print
'Access Token is None'
response = make_response(json.dumps('Current user not connected.'), 401)
response.headers['Content-Type'] = 'application/json'
return response
url = 'https://accounts.google.com/o/oauth2/revoke?token=%s' % login_session['access_token']
h = httplib2.Http()
result = h.request(url, 'GET')[0]
print
'result is '
print
result
if result['status'] == '200':
del login_session['access_token']
del login_session['gplus_id']
del login_session['username']
del login_session['email']
del login_session['picture']
response = make_response(json.dumps('Successfully disconnected.'), 200)
response.headers['Content-Type'] = 'application/json'
return response
else:
response = make_response(json.dumps('Failed to revoke token for given user.', 400))
response.headers['Content-Type'] = 'application/json'
return response
if __name__ == '__main__':
app.run()
The problem with the application is that although that successfully signs in with Google it does not sign in with my website, and after redirecting to index.html again it does not show the user as registered.
Could anybody with experience in Flask help me?
it's easier to write this (it will handle Content-Type header for you):
Code:
# from flask import jsonify
return jsonify('Invalid state parameter.'), 401
Same here:
Code:
@app.route('/catalog.json')
def getJSON():
# Use jsonify() instead of str().
return str(data)
The following snippet doesn't make sense to me:
Code:
state = ''.join(random.choice(string.ascii_uppercase + string.digits)
for x in range(32))
login_session['state'] = state
# Validate state token
if request.args.get('state') != login_session['state']:
# Return error response...
You generate random string and then compare it with another string that you get as an argument for HTTP request. This if-statement will almost always be true.
It's also not clear to me why you're using two separate HTTP client libraries, httplib2 and requests, in the same project. Just stick to one, I recommend the latter, it's easier to use and more popular.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.