Google App Engine Cron Service and Django Rest Framework permissions

· Tech

If you use Google App Engine, you can run tasks using Cron Service. It’s simple. You can create an API endpoint and cron service can make a GET request at a specified time.

To schedule a task, you need to create cron.yaml file, example:

cron:
- description: "Update images"
url: /tasks/update-images
schedule: every day 4:00

It’s essential to secure the /tasks/update-images endpoint. It should be accessible only from the cron service. According to the documentation, you can verify the HTTP header or/and IP address.

Let’s use the HTTP header. All requests from Cron Service contains X-Appengine-Cron: true header. If someone tries to send a request with this header to the API, App Engine will remove it.

The X- headers are stripped by App Engine when they originate from external sources so that you can trust this header.

Using this information, you can create custom DRF permission.

from rest_framework import permissions
class IsCron(permissions.BasePermission):
def has_permission(self, request, view):
if request.META.get("HTTP_X_APPENGINE_CRON"):
return True
return False

Use permission_classes decorator to set the IsCron permission.

from rest_framework.decorators import api_view, permission_classes
from core.permissions.cron import IsCron
@api_view(["GET"])
@permission_classes([IsCron])
def update_images(request):
# ...

Now we are sure that the API endpoint can only be used by the cron service.