Google app engine: security of cron jobs

2020-02-06 06:28发布

问题:

GAE provides cron jobs for scheduled jobs. How do I set some security to prevent someone from executing the http GET directly? In the following example, I can type /updateData anytime in the url field of a browser to execute the job in the following settings:

cron:
- description: daily update of the data in the datastore
  url: /updateData
  schedule: every day 00:00
  timezone: ...

回答1:

In addition to what Paul C said you could create a decorator that checks the X-Appengine-Cron header as illustrated below. Btw, the header can't be spoofed, meaning that if a request that hasn't originated from a cron job has this header, App Engine will change the header's name. You could also write a similar method for tasks, checking X-AppEngine-TaskName in this case.

"""
Decorator to indicate that this is a cron method and applies request.headers check
"""
def cron_method(handler):
    def check_if_cron(self, *args, **kwargs):
        if self.request.headers.get('X-AppEngine-Cron') is None:
            self.error(403)
        else:
            return handler(self, *args, **kwargs)
    return check_if_cron

And use it as:

class ClassName(webapp2.RequestHandler):
    @cron_method
    def get(self):
        ....


回答2:

You need to add

login: admin

to the hander, as detailed here: Securing URLS for Cron

E.G.

application: hello-cron
version: 1
runtime: python27
api_version: 1

handlers:
- url: /updateData
  script: reports.app
  login: admin


回答3:

I am afraid the documentation might not be completely up to date at this point. As Yao Li mentioned, the header you need to check is 'HTTP_X_APPENGINE_CRON' Here is my solution snippet for Python 3.7, Django, and GAE Flex:

from django.http import HttpResponse,HttpResponseForbidden
if 'HTTP_X_APPENGINE_CRON' in request.META:
    if request.META['HTTP_X_APPENGINE_CRON'] == 'true':
        # Handler 
else:
    return HttpResponseForbidden()