Google App Engine can serve static content as well as apps, which makes it a handy place to run sites like this one powered by Jekyll (more info here). But familiar features from other webservers are missing and need reinventing, such as default directory indexes and HTTP Basic Auth. Here’s some info about how to add Basic Auth.
My use case is that I use this website to generate project docs for my freelance work. I prefer to keep this confidential so I wrap it in a simple HTTP Basic Auth user/password, which can be given to anyone needing to access the docs.
This blog post is a good introduction to using HTTP Basic Auth with Google App Engine. It describes how to map a URL to a Python handler that sends the HTTP Basic Auth headers, handles the responses, and deals with authentication.
Once a static URL is mapped to a Python handler to secure its resource via HTTP Basic Auth, that URL cannot be served via a static_dir
or static_files
directive. So if the authentication passes, the handler must read the static file off the file system and send it back in its response. This is described in this Stack Overflow thread.
Handling static files with a Python handler means the files will be served via a frontend instance, which will require one to start or might slow down existing running instances. This is possibly costly or inefficient, so in the approach shown below, I only send *.html to the Python handler, and the CSS and JS remains served straight out of a static dir. It is possible to mix static files and files mapped to a handler by marking the static directory with application_readable: true
in the app.yaml file.
Create your static directory and wrap the HTML in Basic Auth by referring it to a script hander. Everything else in the static dir is served directly as static content. Mark it as application_readable: true to allow the handler to be able to read the HTML content.
app.yaml:
The script handler collects the requests for the static HTML and does the HTTP Auth. If it is OK, it reads the file off the GAE disk and sends it back. This is the same code as the rationalpie blog post, but modified for webapp2 and to include file reading:
auth.py