1
from oauth2client.client import OAuth2WebServerFlow
from oauth2client.tools import run_flow
from oauth2client.file import Storage
import requests    

CLIENT_ID = '9453asfasfaksdfh860b1osoiveogstt.apps.googleusercontent.com'
CLIENT_SECRET = '6gRid8wF7TW8asdfasdftX'


flow = OAuth2WebServerFlow(client_id=CLIENT_ID,
                           client_secret=CLIENT_SECRET,
                           scope='https://www.googleapis.com/auth/admin.directory.user https://www.googleapis.com/auth/admin.directory.user.readonly',
                           redirect_uri='http://example.com/auth_return')

storage = Storage('creds.data') #token details stored here
credentials = run_flow(flow, storage)
tokenhere=credentials.access_token #tokens generated

#send get request with token generated using requests
r=requests.get("https://www.googleapis.com/admin/directory/v1/users?domain=mydomain.ocm",headers={'Authorization': 'Bearer {token}'.format(token=tokenhere)})     
result=r.json()

This is how I have successfully authenticate with google and fetched the users.

Now when I run this. It shows me the page to choose google account to verify and a consent screen for permission.

But the problem is it happens every time I run this.

I know once we authorize next time we don't have to follow that steps again and again but rather directly pass the token or used the saved one.

How is that really implemented. Got no exact clues. Someone please guide me on that. How and where to do that part.For now I have succeeded verifying and getting the authorized token.

EXTRA:The way I am getting tokens might look different because I am trying to fetch the token directly in the console and so have used one module for that purpose and thus looks so

Tara Prasad Gurung
  • 3,422
  • 6
  • 38
  • 76

1 Answers1

0

If I understand correctly this should be what you are looking for:

from oauth2client.client import OAuth2WebServerFlow
from oauth2client.tools import run_flow
from oauth2client.file import Storage
import requests
import os


CLIENT_ID = '9453asfasfaksdfh860b1osoiveogstt.apps.googleusercontent.com'
CLIENT_SECRET = '6gRid8wF7TW8asdfasdftX'

def get_new_token():
    flow = OAuth2WebServerFlow(client_id=CLIENT_ID,
                               client_secret=CLIENT_SECRET,
                               scope='https://www.googleapis.com/auth/admin.directory.user https://www.googleapis.com/auth/admin.directory.user.readonly',
                               redirect_uri='http://example.com/auth_return')
    storage = Storage('creds.data') #token details stored here
    credentials = run_flow(flow, storage)
    tokenhere=credentials.access_token #tokens generated
    return tokenhere

def retrieve_saved_token():
    if os.path.exists('creds.data'):
        with open('creds.data') as creds:
            tokenhere = creds.read()  # Change to reflect how the token data is reflected in your 'creds.data' file
    return tokenhere

def request_page(tokenhere):
    r = requests.get("https://www.googleapis.com/admin/directory/v1/users?domain=mydomain.com",
                     headers={'Authorization': 'Bearer {token}'.format(token=tokenhere)})
    result = r.json()

try:
    tokenhere = retrieve_saved_token()
    request_page(tokenhere)
except:
    tokenhere = get_new_token()
    request_page(tokenhere)

Broken down here are all the components of what was done

Just to be more object oriented I moved your logic into functions:

def get_new_token():
    flow = OAuth2WebServerFlow(client_id=CLIENT_ID,
                               client_secret=CLIENT_SECRET,
                               scope='https://www.googleapis.com/auth/admin.directory.user https://www.googleapis.com/auth/admin.directory.user.readonly',
                               redirect_uri='http://example.com/auth_return')
    storage = Storage('creds.data') #token details stored here
    credentials = run_flow(flow, storage)
    tokenhere=credentials.access_token #tokens generated
    return tokenhere

def request_page(tokenhere):
    r = requests.get("https://www.googleapis.com/admin/directory/v1/users?domain=mydomain.com",
                     headers={'Authorization': 'Bearer {token}'.format(token=tokenhere)})
    result = r.json()

I also added a new function to retrieve a saved token if the token file exists:

def retrieve_saved_token():
    if os.path.exists('creds.data'):
        with open('creds.data') as creds:
            tokenhere = creds.read()  # Change to reflect how the token data is reflected in your 'creds.data' file
    return tokenhere

Finally we get to the part where the logic actually runs.

First it tries to retrieve the token from the file, if the file doesn't exist then an exception would be raised and you would get to the exception logic. The way the try logic is written will also catch if it is successful in retrieving a token but if that token is expired then the request logic should raise an exception.

In the Exception logic it does your original logic of getting a new token and requesting the page with that token

try:
    tokenhere = retrieve_saved_token()
    request_page(tokenhere)
except:
    tokenhere = get_new_token()
    request_page(tokenhere)

EDIT 1

I am assuming that you don't just want to request the page but also manipulate the data on the page. To do that you would have another function that pulls data off the page by looking for tags in the json object 'result' that you created. I call this function 'do_something_with_request_function()' in the code below.

The first Try/Except will check if a token file exists, if it does then grab that token and use it, if it doesn't then it will generate a new token.

The second try except has a chance of passing in an expired token. So lets assume two scenarios.
Scenario 1: you pass in a valid token, you get the page you need in the request. Your method that you use to parse the data on the page will look for specific fields that exist on that page, everything works fine.
Scenario 2: you pass an invalid token, you get an error page for expired/invalid token. Your method that parses that page to json and tries to manipulate the data would throw errors if it didn't find a value that would normally exist on the actual page you are trying to get to. This would force the code to jump to the except block.
The except block generates a new token, passes that in to request the page again and will process your data properly.

try:
    tokenhere = retrieve_saved_token()
except:
    tokenhere = get_new_token()
try:
    request_page(tokenhere)
    do_something_with_request_function(result)
except:
    tokenhere = get_new_token()
    request_page(tokenhere)
    do_something_with_request_function(result)
HackerShark
  • 211
  • 2
  • 7
  • so its all about getting the token from the saved location. But what about the token expires right how to handle that, what can be done for that – Tara Prasad Gurung May 04 '17 at 19:40
  • I changed the logic with comments. The new code is listed under **EDIT 1**. This should handle your scenario of if a token expires. – HackerShark May 05 '17 at 14:51
  • With this We need to reauthorized, If we dont use the refresh toke, Generating new token means making the user reauthorized again which he did once. Right – Tara Prasad Gurung May 06 '17 at 13:56
  • Ok thats fine but how do really implement the token refresh, when looking at credentials = run_flow(flow, storage) the credentials returns the refresh_token value too.But can find the right way to implement it.So that users dont need authorization again – Tara Prasad Gurung May 06 '17 at 19:07
  • I am not too familiar with how refresh token's work myself but I found these two other stackoverflow links that seem to explain ways to handle it. [first link](http://stackoverflow.com/questions/27146469/how-to-use-a-refresh-token-to-get-a-new-access-token-using-flask-oauthlib) [second link](http://stackoverflow.com/questions/27771324/google-api-getting-credentials-from-refresh-token-with-oauth2client-client) @TaraPrasadGurung – HackerShark May 10 '17 at 13:37