gcloud auth print-access-token
给了我一个我可以在以后使用的Bearer令牌;但是,这是一个shell命令。如何通过Google Cloud Python API以编程方式获取一个?
我看到使用prior example的oauth2client,但oauth2client
现在已被弃用。我如何使用google.auth和oauthlib做到这一点?
答案取决于您的环境以及您希望如何创建/获取凭据。
什么是Google云端凭据?
Google Cloud凭据是OAuth 2.0令牌。此令牌至少有一个Access Token
和可选的Refresh Token
,Client ID Token
,以及支持参数,如expiration
,Service Account Email
或Client Email
等。
Google Cloud API中的重要项目是Access Token
。此令牌授权访问云。此令牌可用于curl
等程序,python
等软件,不需要SDK。 Access Token
用于HTTP Authorization
标头。
什么是访问令牌?
访问令牌是由Google生成的不透明值,它源自签名JWT,更准确地称为JWS。 JWT由头和声明(有效载荷)Json结构组成。这两个Json结构使用服务帐户的私钥进行签名。这些值是base64编码和连接以创建访问密钥。
访问令牌的格式为:base64(header) + '.' + base64(payload) + '.' + base64(signature)
。
以下是JWT的示例:
标题:
{
"alg": "RS256",
"typ": "JWT",
"kid": "42ba1e234ac91ffca687a5b5b3d0ca2d7ce0fc0a"
}
有效载荷:
{
"iss": "[email protected]",
"iat": 1493833746,
"aud": "myservice.appspot.com",
"exp": 1493837346,
"sub": "[email protected]"
}
使用访问令牌:
将启动VM实例的示例。替换PROJECT_ID,ZONE和INSTANCE_NAME。此示例适用于Windows。
curl -v -X GET -H "Authorization: Bearer <access_token_here>" ^
https://www.googleapis.com/compute/v1/projects/%PROJECT_ID%/zones/%ZONE%/instances/%INSTANCE_NAME%/start
计算引擎服务帐户:
Dustin的答案对于这种情况是正确的,但我会在完整性方面加入一些额外的信息。
这些凭据由GCP自动为您创建,并从VM实例元数据中获取。权限由Google控制台中的Cloud API access scopes
控制。
但是,这些凭据有一些限制。要修改凭据,必须先停止VM实例。此外,并非所有权限(角色)都受支持。
from google.auth import compute_engine
cred = compute_engine.Credentials()
服务帐户凭据:
除非您了解所有类型的凭据及其用例,否则这些凭据将用于除gcloud
和gsutil
之外的所有内容。了解这些凭据将使编写程序时使用Google Cloud变得更加简单。从Google服务帐户Json文件中获取凭据非常简单。要记下的唯一项目是凭据到期(通常为60分钟),需要刷新或重新创建。
不建议使用gcloud auth print-access-token
。服务帐户凭据是Google推荐的方法。
这些凭据由Console,gcloud或程序/ API创建。权限由IAM分配给信用卡,并在Compute Engine,App Engine,Firestore,Kubernetes等内部以及Google Cloud之外的其他环境中运行。这些凭据从Google Cloud下载并存储在Json文件中。注意scopes
参数。这定义了授予生成的凭证对象的权限。
SCOPES = ['https://www.googleapis.com/auth/sqlservice.admin']
SERVICE_ACCOUNT_FILE = 'service-account-credentials.json'
from google.oauth2 import service_account
cred = service_account.Credentials.from_service_account_file(
SERVICE_ACCOUNT_FILE, scopes=SCOPES)
Google OAuth 2.0凭据:
这些凭据源自完整的OAuth 2.0流程。启动浏览器访问Google帐户以授权访问时,会生成这些凭据。此过程要复杂得多,需要大量代码才能实现,并且需要内置的Web服务器来进行授权回调。
此方法提供了其他功能,例如能够在浏览器中运行所有内容,例如,您可以创建云存储文件浏览器,但请注意您了解安全隐患。此方法是用于支持Google登录等的技术。我希望在允许在网站上发布之前使用此方法对用户进行身份验证等。正确授权的OAuth 2.0身份和范围可能无穷无尽。
使用google_auth_oauthlib
的示例代码:
from google_auth_oauthlib.flow import InstalledAppFlow
flow = InstalledAppFlow.from_client_secrets_file(
'client_secrets.json',
scopes=scope)
cred = flow.run_local_server(
host='localhost',
port=8088,
authorization_prompt_message='Please visit this URL: {url}',
success_message='The auth flow is complete; you may close this window.',
open_browser=True)
使用requests_oauthlib
库的示例代码:
from requests_oauthlib import OAuth2Session
gcp = OAuth2Session(
app.config['gcp_client_id'],
scope=scope,
redirect_uri=redirect_uri)
# print('Requesting authorization url:', authorization_base_url)
authorization_url, state = gcp.authorization_url(
authorization_base_url,
access_type="offline",
prompt="consent",
include_granted_scopes='true')
session['oauth_state'] = state
return redirect(authorization_url)
# Next section of code after the browser approves the request
token = gcp.fetch_token(
token_url,
client_secret=app.config['gcp_client_secret'],
authorization_response=request.url)
虽然上面的答案非常有用,但它错过了一个重要的观点 - 从google.auth.default()
或compute_engine.Credentials()
获得的凭证对象将不会有令牌。那么回到gcloud auth print-access-token
的程序化替代品的原始问题,我的答案是:
import google.auth
import google.auth.transport.requests
creds, projects = google.auth.default()
# creds.valid is False, and creds.token is None
# Need to refresh credentials to populate those
auth_req = google.auth.transport.requests.Request()
creds.refresh(auth_req)
# Now you can use creds.token
我正在使用官方的google-auth软件包和default credentials,它将让你在本地开发和远程GCE / GKE应用程序上运行。
太糟糕了,这没有正确记录,我不得不阅读google-auth code来确定如何获取令牌。