|
| 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) |
0 commit comments