Created
January 10, 2015 21:46
-
-
Save lithuak/bba7724396e2072623d4 to your computer and use it in GitHub Desktop.
Google OAuth Python
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Google OAuth 3.0 auth provider | |
from flask import request, redirect, session, url_for, current_app | |
from urllib import quote_plus | |
import requests | |
from util.common import make_url, url_for_view | |
client_id = "***" | |
client_secret = "***" | |
def _redir_host(): | |
return "http://" + current_app.config["BASE_DOMAIN"] | |
class GoogleAuthProvider(): | |
def __init__(self, blueprint): | |
blueprint.add_url_rule("/google/cb", view_func=self.ga_callback) | |
def first_step_url(self, return_url): | |
return make_url("https://accounts.google.com/o/oauth2/auth", { | |
"response_type": "code", | |
"client_id": client_id, | |
"redirect_uri": _redir_host() + url_for("auth.ga_callback"), | |
"scope": "email profile", | |
"state": return_url}) | |
def ga_callback(self): | |
try: | |
# 0. handle possible error | |
error = request.args.get("error", "") | |
if error: | |
raise Exception("Google auth failed, says: " + error) | |
# 1. get "code" from GA | |
return_url = request.args.get("state", "/") | |
code = request.args.get("code", "") | |
if not code: | |
raise Exception("Absent or empty <code> param") | |
# 2. get "in_token", identifying current user | |
in_token = session.get("in_token", "") | |
if not in_token: | |
raise Exception("Absent or empty <in_token> param") | |
# 3. exchange GA code to api access token | |
access_token = self._get_access_token(code) | |
# 4. with access token - get user info | |
email, fullname = self._get_user_info(access_token) | |
# 5. send to login.py | |
import auth | |
auth.do_authenticate_user(in_token, "ga", email, fullname) | |
# 6. redirect to return_url | |
return redirect(return_url) | |
except Exception as e: | |
# TODO: log exception | |
return redirect(url_for("auth.login", return_url=return_url, error=e.message)) | |
def _get_access_token(self, code): | |
r = requests.post("https://accounts.google.com/o/oauth2/token", data={ | |
"code": code, | |
"client_id": client_id, | |
"client_secret": client_secret, | |
"redirect_uri": _redir_host() + url_for("auth.ga_callback"), | |
"grant_type": "authorization_code" | |
}) | |
try: | |
data = r.json() | |
return data["access_token"] | |
except Exception as e: | |
raise Exception("Failed to exchange google code to api access token, (" + e.message + ")") | |
def _get_user_info(self, access_token): | |
r = requests.get("https://www.googleapis.com/oauth2/v1/userinfo?alt=json&access_token=" + access_token) | |
try: | |
data = r.json() | |
return data["email"], data["name"] | |
except Exception as e: | |
raise Exception("Failed to get email and full name from google API: (" + e.message + ")") | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment