Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 57de3e0

Browse filesBrowse files
author
Jon Wayne Parrott
authored
Add web sample for using google-auth for end-user auth (GoogleCloudPlatform#1127)
* Add web sample for using google-auth for end-user auth Change-Id: I90856d5da694b9eab1b363f7982638482e10429a * Use apiclient Change-Id: Icb43629fa835682eeb0a248dbb56e12b15d0dd15 * Address review comments Change-Id: I3f7492601a6ec7f64dab611928dc1d6c5a23d9af * Fix missing redirect uri Change-Id: I98ea11e842c679caf944b134e745013962c5c34a * Fix some wording Change-Id: I44d4c690c8fb3702988cb303d4afc9872331bb32
1 parent a75e025 commit 57de3e0
Copy full SHA for 57de3e0

File tree

Expand file treeCollapse file tree

3 files changed

+163
-0
lines changed
Filter options
Expand file treeCollapse file tree

3 files changed

+163
-0
lines changed

‎auth/end-user/web/main.py

Copy file name to clipboard
+119Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
# Copyright 2017 Google Inc. All Rights Reserved.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
"""An example web application that obtains authorization and credentials from
16+
an end user.
17+
18+
This sample is used on
19+
https://developers.google.com/identity/protocols/OAuth2WebServer. Please
20+
refer to that page for instructions on using this sample.
21+
22+
Notably, you'll need to obtain a OAuth2.0 client secrets file and set the
23+
``GOOGLE_CLIENT_SECRETS`` environment variable to point to that file.
24+
"""
25+
26+
import os
27+
28+
import flask
29+
import google.oauth2.credentials
30+
import google_auth_oauthlib.flow
31+
import googleapiclient.discovery
32+
33+
# The path to the client-secrets.json file obtained from the Google API
34+
# Console. You must set this before running this application.
35+
CLIENT_SECRETS_FILENAME = os.environ['GOOGLE_CLIENT_SECRETS']
36+
# The OAuth 2.0 scopes that this application will ask the user for. In this
37+
# case the application will ask for basic profile information.
38+
SCOPES = ['email', 'profile']
39+
40+
app = flask.Flask(__name__)
41+
# TODO: A secret key is included in the sample so that it works but if you
42+
# use this code in your application please replace this with a truly secret
43+
# key. See http://flask.pocoo.org/docs/0.12/quickstart/#sessions.
44+
app.secret_key = 'TODO: replace with a secret value'
45+
46+
47+
@app.route('/')
48+
def index():
49+
if 'credentials' not in flask.session:
50+
return flask.redirect('authorize')
51+
52+
# Load the credentials from the session.
53+
credentials = google.oauth2.credentials.Credentials(
54+
**flask.session['credentials'])
55+
56+
# Get the basic user info from the Google OAuth2.0 API.
57+
client = googleapiclient.discovery.build(
58+
'oauth2', 'v2', credentials=credentials)
59+
60+
response = client.userinfo().v2().me().get().execute()
61+
62+
return str(response)
63+
64+
65+
@app.route('/authorize')
66+
def authorize():
67+
# Create a flow instance to manage the OAuth 2.0 Authorization Grant Flow
68+
# steps.
69+
flow = google_auth_oauthlib.flow.Flow.from_client_secrets_file(
70+
CLIENT_SECRETS_FILENAME, scopes=SCOPES)
71+
flow.redirect_uri = flask.url_for('oauth2callback', _external=True)
72+
authorization_url, state = flow.authorization_url(
73+
# This parameter enables offline access which gives your application
74+
# an access token and a refresh token for the user's credentials.
75+
access_type='offline',
76+
# This parameter enables incremental auth.
77+
include_granted_scopes='true')
78+
79+
# Store the state in the session so that the callback can verify the
80+
# authorization server response.
81+
flask.session['state'] = state
82+
83+
return flask.redirect(authorization_url)
84+
85+
86+
@app.route('/oauth2callback')
87+
def oauth2callback():
88+
# Specify the state when creating the flow in the callback so that it can
89+
# verify the authorization server response.
90+
state = flask.session['state']
91+
flow = google_auth_oauthlib.flow.Flow.from_client_secrets_file(
92+
CLIENT_SECRETS_FILENAME, scopes=SCOPES, state=state)
93+
flow.redirect_uri = flask.url_for('oauth2callback', _external=True)
94+
95+
# Use the authorization server's response to fetch the OAuth 2.0 tokens.
96+
authorization_response = flask.request.url
97+
flow.fetch_token(authorization_response=authorization_response)
98+
99+
# Store the credentials in the session.
100+
credentials = flow.credentials
101+
flask.session['credentials'] = {
102+
'token': credentials.token,
103+
'refresh_token': credentials.refresh_token,
104+
'token_uri': credentials.token_uri,
105+
'client_id': credentials.client_id,
106+
'client_secret': credentials.client_secret,
107+
'scopes': credentials.scopes
108+
}
109+
110+
return flask.redirect(flask.url_for('index'))
111+
112+
113+
if __name__ == '__main__':
114+
# When running locally with Flask's development server this disables
115+
# OAuthlib's HTTPs verification. When running in production with a WSGI
116+
# server such as gunicorn this option will not be set and your application
117+
# *must* use HTTPS.
118+
os.environ['OAUTHLIB_INSECURE_TRANSPORT'] = '1'
119+
app.run('localhost', 8080, debug=True)

‎auth/end-user/web/main_test.py

Copy file name to clipboard
+38Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
# Copyright 2017 Google Inc. All Rights Reserved.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
import pytest
16+
17+
import main
18+
19+
# Note: samples that do end-user auth are difficult to test in an automated
20+
# way. These tests are basic sanity checks.
21+
22+
23+
@pytest.fixture
24+
def client():
25+
main.app.testing = True
26+
return main.app.test_client()
27+
28+
29+
def test_index_wo_credentials(client):
30+
r = client.get('/')
31+
assert r.status_code == 302
32+
assert r.headers['location'].endswith('/authorize')
33+
34+
35+
def test_authorize(client):
36+
r = client.get('/authorize')
37+
assert r.status_code == 302
38+
assert r.headers['location'].startswith('https://accounts.google.com')

‎auth/end-user/web/requirements.txt

Copy file name to clipboard
+6Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
google-auth==1.1.0
2+
google-auth-oauthlib==0.1.1
3+
google-auth-httplib2==0.0.2
4+
google-api-python-client==1.6.3
5+
flask==0.12.2
6+
requests==2.18.4

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.