[Solved]-Htaccess on heroku for django app

16👍

As @mipadi said, you can’t use htaccess on Heroku, but you can create a middleware for that:

from django.conf import settings
from django.http import HttpResponse
from django.utils.translation import ugettext as _


def basic_challenge(realm=None):
    if realm is None:
        realm = getattr(settings, 'WWW_AUTHENTICATION_REALM', _('Restricted Access'))
    # TODO: Make a nice template for a 401 message?
    response =  HttpResponse(_('Authorization Required'), mimetype="text/plain")
    response['WWW-Authenticate'] = 'Basic realm="%s"' % (realm)
    response.status_code = 401
    return response

def basic_authenticate(authentication):
    # Taken from paste.auth
    (authmeth, auth) = authentication.split(' ',1)
    if 'basic' != authmeth.lower():
        return None
    auth = auth.strip().decode('base64')
    username, password = auth.split(':',1)
    AUTHENTICATION_USERNAME = getattr(settings, 'BASIC_WWW_AUTHENTICATION_USERNAME')
    AUTHENTICATION_PASSWORD = getattr(settings, 'BASIC_WWW_AUTHENTICATION_PASSWORD')
    return username == AUTHENTICATION_USERNAME and password == AUTHENTICATION_PASSWORD

class BasicAuthenticationMiddleware(object):
    def process_request(self, request):
        if not getattr(settings, 'BASIC_WWW_AUTHENTICATION', False):
            return
        if 'HTTP_AUTHORIZATION' not in request.META:
            return basic_challenge()
        authenticated = basic_authenticate(request.META['HTTP_AUTHORIZATION'])
        if authenticated:
            return
        return basic_challenge()

Then you need to define in settings.py:

BASIC_WWW_AUTHENTICATION_USERNAME = "your user"
BASIC_WWW_AUTHENTICATION_PASSWORD = "your pass"
BASIC_WWW_AUTHENTICATION = True

8👍

I was able to use .htaccess files on heroku with the cedar stack.

  1. Procfile needs to specify a script for the web nodes:

    web:    sh www/conf/web-boot.sh
    
  2. The conf/web-boot.sh slipstreams the include of a apache configuration file, e.g.:

  3. A conf/httpd/default.conf then can allow override, as you know it from apache.

You can then just use .htaccess files. The whole process is documented in detail in my blog post PHP on Heroku again of which one part is about the apache configuration. The step in 2. including your own httpd configuration basically is:

sed -i 's/Listen 80/Listen '$PORT'/' /app/apache/conf/httpd.conf
sed -i 's/^DocumentRoot/# DocumentRoot/' /app/apache/conf/httpd.conf
sed -i 's/^ServerLimit 1/ServerLimit 8/' /app/apache/conf/httpd.conf
sed -i 's/^MaxClients 1/MaxClients 8/' /app/apache/conf/httpd.conf

for var in `env|cut -f1 -d=`; do
  echo "PassEnv $var" >> /app/apache/conf/httpd.conf;
done
echo "Include /app/www/conf/httpd/*.conf" >> /app/apache/conf/httpd.conf
touch /app/apache/logs/error_log
touch /app/apache/logs/access_log
tail -F /app/apache/logs/error_log &
tail -F /app/apache/logs/access_log &
export LD_LIBRARY_PATH=/app/php/ext
export PHP_INI_SCAN_DIR=/app/www
echo "Launching apache"
exec /app/apache/bin/httpd -DNO_DETACH

I hope this is helpful. I used this for .htaccess and for changing the webroot.

👤hakre

-2👍

You can’t use .htaccess, because Heroku apps aren’t served with Apache. You can use Django authentication, though.

Or you can serve the files from another server that is using Apache.

👤mipadi

Leave a comment