Google App Engine に 2 つのアプリがあり、どちらも同じアカウントで実行されており、一方は HTTPS 経由で他方が提供するサービスを呼び出します。最初のアプリのみが 2 番目のアプリの呼び出しを許可されるようにするための推奨される方法は何ですか?
または、特定のエンドポイントが同じ GAE アカウントで実行されているアプリによってのみ呼び出されるように指定する方法はありますか?
Google App Engine に 2 つのアプリがあり、どちらも同じアカウントで実行されており、一方は HTTPS 経由で他方が提供するサービスを呼び出します。最初のアプリのみが 2 番目のアプリの呼び出しを許可されるようにするための推奨される方法は何ですか?
または、特定のエンドポイントが同じ GAE アカウントで実行されているアプリによってのみ呼び出されるように指定する方法はありますか?
他の人が指摘しているように、記入されているヘッダー X-Appengine-Inbound-Appid に依存するのが最も簡単な解決策です。私も最近似たようなことがありましたが、URLFetch が利用できなかった (GAE Node.js) ため、X-Appengine-Inbound-Appid を使用できませんでした。OAuth で認証されたサービス アカウントを使用して問題を解決する方法を次に示します。
送信者側では、サービス アカウントを設定する必要があります: https://developers.google.com/identity/protocols/OAuth2ServiceAccount#creatinganaccount
次に、そのアプリで、サービス アカウントの資格情報を取得する必要があります: https://developers.google.com/identity/protocols/application-default-credentials
次に、認証情報を使用して authClient を作成し、それを使用してリクエストを送信できます。authClient に OAuth スコープを追加する必要があります。使用する最も論理的なものは ですhttps://www.googleapis.com/auth/userinfo.email
。これにより、受信者は送信者のサービス アカウントのメール アドレスを取得できます。https://developers.google.com/identity/protocols/googlescopes
(送信者)Node.jsで動作させるためのコードは次のとおりです。
process.env.GOOGLE_APPLICATION_CREDENTIALS = <PATH TO CREDENTIALS FILE>
google.auth.getApplicationDefault((err, authClient) => {
if (err) {
console.log("Failed to get default credentials: ", String(err));
return;
}
if (authClient.createScopedRequired && authClient.createScopedRequired()) {
authClient = authClient.createScoped([
'https://www.googleapis.com/auth/userinfo.email'
]);
}
auth_client.request({
url: <RECEIVER URL>,
method: "GET"
}, (error, result, response) => {
// Process response
});
});
次に、受信者側で、電子メール アドレスが送信者のサービス アカウントの電子メール アドレスと一致することを確認する必要があります。アプリ エンジンがローカルで呼び出されると、OAuth リクエストが適切に認証されないため、ローカルでテストする場合は、URL フェッチを実行してリクエストを自分で確認する必要があります。
受信者のパイソン:
scope = "https://www.googleapis.com/auth/userinfo.email"
allowed_users = set([
"<SENDER SERVICE ACCOUNT EMAIL>"
])
IS_DEV = os.environ["SERVER_SOFTWARE"][:3] == "Dev"
class MyHandler(webapp2.RequestHandler):
def get(self, clientId):
user = self.get_current_user()
if user in allowed_users:
# Do whatever you wanted
def get_current_user(self):
if IS_DEV:
token = self.request.headers.get("Authorization")[len("Bearer "):]
response = urlfetch.fetch(
"https://www.googleapis.com/oauth2/v3/tokeninfo?access_token=%s" % token
)
return json.loads(response.content)["email"]
else:
return oauth.get_current_user(scope)
アプリケーションで「X-Appengine-Inbound-Appid」ヘッダーをチェックし、アプリ ID が正しいことを確認します。このヘッダーは、リクエストが別の Google App Engine アプリによって行われた場合にのみ存在し、ユーザーが変更することはできません。
Python を使用している場合は、次のことができます。
import webapp2
AUTHORIZED_APPS = ('my-first-app', 'my-other-app')
class MyHandler(webapp2.RequestHandler):
def dispatch(self):
app_id = self.request.headers.get('X-Appengine-Inbound-Appid', None)
if app_id in AUTHORIZED_APPS:
super(MyHandler, self).dispatch()
else:
self.abort(403)
これにより、ヘッダーに X-Appengine-Inbound-Appid がないリクエストに対して 403 が発生します。
また、urlfetch を使用してあるアプリケーションから別のアプリケーションにリクエストを送信する場合は、follow_redirects=Falseを設定するか、ヘッダーが追加されないようにしてください。
App Engine のApplication Identityサービスをチェックしてみてください。
最も簡単な方法 (この場合は十分) は、HTTP ヘッダーにシークレットを含め、サービス側でそれをチェックすることです。
これでうまくいく場合はDunnoですが、app.yamlのURLハンドラーに「login:admin」を追加してみてください。
cron/タスクキュージョブで機能します
https://developers.google.com/appengine/docs/python/config/cron#Securing_URLs_for_Cron