Python 如何使用gmail进行一次身份验证并使用生成的令牌? 这就是我如何成功地通过谷歌认证并获取用户的方法。

Python 如何使用gmail进行一次身份验证并使用生成的令牌? 这就是我如何成功地通过谷歌认证并获取用户的方法。,python,authentication,oauth-2.0,gmail-api,google-python-api,Python,Authentication,Oauth 2.0,Gmail Api,Google Python Api,现在当我运行这个。它向我显示了选择谷歌账户进行验证的页面和许可的同意屏幕 但问题是每次我运行这个时都会发生 我知道,一旦我们下一次授权,我们不必一次又一次地遵循这些步骤,而是直接传递令牌或使用保存的令牌 这是如何真正实现的。没有确切的线索。请有人在这方面指导我。如何以及在何处执行该部分。目前,我已成功验证并获得授权令牌 额外:我获取令牌的方式可能看起来有所不同,因为我试图直接在控制台中获取令牌,因此使用了一个模块来实现该目的,因此如果我理解正确,那么看起来就应该是您所寻找的: from oaut

现在当我运行这个。它向我显示了选择谷歌账户进行验证的页面和许可的同意屏幕

但问题是每次我运行这个时都会发生

我知道,一旦我们下一次授权,我们不必一次又一次地遵循这些步骤,而是直接传递令牌或使用保存的令牌

这是如何真正实现的。没有确切的线索。请有人在这方面指导我。如何以及在何处执行该部分。目前,我已成功验证并获得授权令牌


额外:我获取令牌的方式可能看起来有所不同,因为我试图直接在控制台中获取令牌,因此使用了一个模块来实现该目的,因此如果我理解正确,那么看起来就应该是您所寻找的:

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()
以下是所做工作的所有组成部分

为了更加面向对象,我将您的逻辑移到了函数中:

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)
我还添加了一个新函数,用于在令牌文件存在时检索保存的令牌:

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()
最后我们进入逻辑实际运行的部分

首先,它尝试从文件中检索令牌,如果文件不存在,则会引发异常,您将进入异常逻辑。 如果try逻辑成功地检索到令牌,那么try逻辑的写入方式也将捕获该令牌,但是如果该令牌过期,那么请求逻辑将引发异常

在异常逻辑中,它执行获取新令牌并使用该令牌请求页面的原始逻辑

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
编辑1

我假设您不仅要请求页面,还要操作页面上的数据。要做到这一点,您可以使用另一个函数,通过在您创建的json对象“result”中查找标记,从页面中提取数据。在下面的代码中,我将此函数称为“do_something_with_request_function()”

第一次Try/Except将检查令牌文件是否存在,如果存在,则获取该令牌并使用它,如果不存在,则将生成一个新令牌

第二次尝试有机会传入过期的令牌。因此,让我们假设两种情况。
场景1:您传入了一个有效的令牌,就得到了请求中所需的页面。您用于解析页面上数据的方法将查找该页面上存在的特定字段,一切正常。
场景2:您传递了一个无效令牌,您将获得一个过期/无效令牌的错误页面。如果您将该页面解析为json并尝试操作数据的方法没有找到通常存在于您试图访问的实际页面上的值,则该方法将抛出错误。这将迫使代码跳转到except块。
except块生成一个新的令牌,传入该令牌以再次请求页面,并将正确处理您的数据

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

如果我理解正确,这应该是您正在寻找的:

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()
以下是所做工作的所有组成部分

为了更加面向对象,我将您的逻辑移到了函数中:

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)
我还添加了一个新函数,用于在令牌文件存在时检索保存的令牌:

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()
最后我们进入逻辑实际运行的部分

首先,它尝试从文件中检索令牌,如果文件不存在,则会引发异常,您将进入异常逻辑。 如果try逻辑成功地检索到令牌,那么try逻辑的写入方式也将捕获该令牌,但是如果该令牌过期,那么请求逻辑将引发异常

在异常逻辑中,它执行获取新令牌并使用该令牌请求页面的原始逻辑

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
编辑1

我假设您不仅要请求页面,还要操作页面上的数据。要做到这一点,您可以使用另一个函数,通过在您创建的json对象“result”中查找标记,从页面中提取数据。在下面的代码中,我将此函数称为“do_something_with_request_function()”

第一次Try/Except将检查令牌文件是否存在,如果存在,则获取该令牌并使用它,如果不存在,则将生成一个新令牌

第二次尝试有机会传入过期的令牌。因此,让我们假设两种情况。
场景1:您传入了一个有效的令牌,就得到了请求中所需的页面。您用于解析页面上数据的方法将查找该页面上存在的特定字段,一切正常。
场景2:您传递了一个无效令牌,您将获得一个过期/无效令牌的错误页面。如果您将该页面解析为json并尝试操作数据的方法没有找到通常存在于您试图访问的实际页面上的值,则该方法将抛出错误。这将迫使代码跳转到except块。
except块生成一个新的令牌,传入该令牌以再次请求页面,并将正确处理您的数据

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

因此,所有这些都是关于从保存的位置获取令牌。但是令牌过期了怎么办?如何处理,可以做些什么?我用注释改变了逻辑。新代码列在“编辑1”下。这应该可以处理令牌过期的情况。有了它,我们需要重新授权,如果我们不使用刷新托克,生成新令牌意味着让用户重新授权,就像他曾经做过的那样。好的,好的,但是当查看凭证=运行流(流、存储)时,如何真正实现令牌刷新凭据也会返回refresh_令牌值。但是可以找到正确的方法来实现它。这样用户就不需要授权了。我自己也不太熟悉refresh令牌的工作方式,但我找到了另外两个stackoverflow链接,它们似乎解释了处理它的方法@Taraprasadgurung所以这一切都是为了从t获得代币