Come altri hanno fatto notare, facendo leva sulla intestazione X-AppEngine-Inbound-AppID viene compilato è la soluzione più semplice. Recentemente ho avuto un problema simile, ma non ho potuto utilizzare X-Appengine-Inbound-Appid perché URLFetch non era disponibile (Node.js GAE). Ecco come risolvere il problema utilizzando gli account di servizio autenticati tramite OAuth.
Sul lato mittente si desidera impostare un account di servizio: https://developers.google.com/identity/protocols/OAuth2ServiceAccount#creatinganaccount
allora in quel app che sarà necessario per ottenere le credenziali dell'account di servizio: https://developers.google.com/identity/protocols/application-default-credentials
Quindi è possibile utilizzare le credenziali per fare un authClient, che è possibile utilizzare per inviare la richiesta. Dovrai aggiungere un ambito OAuth al tuo authClient. Il più logico da usare è https://www.googleapis.com/auth/userinfo.email
. Ciò consentirà al destinatario di ottenere l'indirizzo email dell'account di servizio del mittente. https://developers.google.com/identity/protocols/googlescopes
Qui è il codice per farlo funzionare in (mittente) 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
});
});
Poi sul lato del ricevitore è necessario verificare l'indirizzo e-mail corrisponde l'indirizzo e-mail del account di servizio del mittente. Quando il motore dell'app viene richiamato localmente, la richiesta OAuth non viene autenticata correttamente, quindi se vuoi testare localmente dovrai eseguire un recupero URL per verificare tu stesso la richiesta.
Ricevitore Python:
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)
Non è possibile che qualcuno che conosce gli ID app delle app autorizzate li impersonino aggiungendo l'intestazione manualmente? –
No. "Questa intestazione non può essere falsificata da altre app o servizi esterni: è sterilizzata dal sistema App Engine" http://stackoverflow.com/a/7961397/789417 –
Il codice sopra riportato non funzionerà in realtà se il L'intestazione X-Appengine-Inbound-Appid non è presente. Se l'intestazione non è presente, app_id sarà None. Controllando se None è in una tupla, verrà generato un errore TypeError. Ciò che in realtà desideri è che AUTHORIZED_APPS sia un elenco. Controllare se None è in una lista è una cosa valida da fare in Python. – timbo