例えば、BigQueryの前段にCloud EndpointsによるAPI層を構築する場合、GAE SDKのdev_appserverからBigQueryへ接続したくなる。
Developers Consoleでサービスアカウントを作成すると、P12キーがダウンロードされる。
P12キーとは、PKCS12形式の秘密鍵である。
oauth2client
が利用しているPyCrypto
は、PKCS12形式をサポートしていない。
そのまま使おうとすると、
NotImplementedError: PKCS12 format is not supported by the PyCrypto library. Try converting to a "PEM" (openssl pkcs12 -in xxxxx.p12 -nodes -nocerts > privatekey.pem) or using PyOpenSSL if native code is an option.
といったNotImplementedError
が発生するので、メッセージ通りに秘密鍵を変換すればよい。
$ openssl pkcs12 -in xxxxx.p12 -nodes -nocerts > privatekey.pem
Enter Import Password:
サービスアカウントの秘密鍵のパスワードは、notasecret
決め打ちになっている。
サンプルコード
# -*- coding: utf-8 -*-
import os
from google.appengine.api import memcache
import apiclient
import httplib2
import oauth2client
# OAuth2.0のSCOPEを列挙する。
# 例) https://cloud.google.com/bigquery/authentication#oauthbasics
BigQuery_SCOPE = ('https://www.googleapis.com/auth/bigquery',)
def get_bigquery_client():
# dev_appserverで実行しているか、判定する。環境変数`SERVER_SOFTWARE`が`Dev`から始まる。
if os.environ.get('SERVER_SOFTWARE', 'Dev').startswith('Dev'):
# PEMファイルを読み取り専用で開く。
with open('privatekey.pem', 'rb') as f:
# Credentials object used for OAuth 2.0 Signed JWT assertion grants.
# http://google-api-python-client.googlecode.com/hg/docs/epy/oauth2client.client.SignedJwtAssertionCredentials-class.html
credentials = oauth2client.client.SignedJwtAssertionCredentials(
service_account_name = '...@developer.gserviceaccount.com',
private_key = f.read(),
scope = BigQuery_SCOPE,
)
else:
# Credentials object for App Engine Assertion Grants
# http://google-api-python-client.googlecode.com/hg/docs/epy/oauth2client.appengine.AppAssertionCredentials-class.html
credentials = oauth2client.appengine.AppAssertionCredentials(scope=BigQuery_SCOPE)
# キャッシュ利用にmemcacheを設定したHTTPクライアント。
http = credentials.authorize(httplib2.Http(memcache))
# Google Cloud Endpointsを指定して、APIクライアントを返す。
return apiclient.discovery.build('bigquery', 'v2', http=http)
よくあるエラー
IOError: [Errno 13] file not accessible: 'privatekey.pem'
GAEプロジェクト下のファイルにしかアクセスできないので、GAEプロジェクト下のディレクトリへ秘密鍵を移動する。
ValueError: RSA key format is not supported
RSA形式ではなく、PEM形式へ変換する。
ValueError: PEM encryption format not supported.
PEMフレーズは、解除しなければならない。
AccessTokenRefreshError: invalid_grant
service_account_name
に指定するのは、サービスアカウントのメールアドレスである。クライアントIDではない。