2012-02-22 17 views
11

Il titolo riassume molto la mia domanda. Mi piacerebbe proteggere con password alcuni file nella mia app django che vive su heroku.
Se non riesco a utilizzare htaccess qualcuno ha suggerimenti su cos'altro potrei usare? Grazie.htaccess su heroku per django app

+1

Preferisco non utilizzare nulla di specifico per django perché ho un server di test, produzione e demo per gestire – mea36

+0

Perché non utilizzare 'SITE_ID' e la struttura dei siti per differenziare? – Josh

risposta

16

Come @mipadi Detto questo, non è possibile utilizzare .htaccess su Heroku, ma è possibile creare un middleware per questo:

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() 

Poi è necessario definire in settings.py:

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

Questo ha funzionato alla grande. Come posso modificarlo in modo che funzioni solo per URL specifici? – mea36

+2

In realtà l'ho capito usando request.META ['PATH_INFO'] per controllare l'url e tornare se non voglio che l'url protetto da password – mea36

+0

Impressionante, sono felice di aiutarti. –

-2

Non è possibile utilizzare .htaccess, perché le app di Heroku non vengono servite con Apache. È possibile utilizzare Django authentication, tuttavia.

Oppure è possibile servire i file da un altro server che è utilizzando Apache.

+0

Uso già l'auth di django nell'app – mea36

+1

Chi dice che le app di Heroku non vengono servite con Apache? Ho una configurazione di apache che funziona bene. A quale stack appartiene la tua risposta? Non ho problemi ad usare i file .htaccess su cedar, l'impostazione di base è [documentata sul mio blog] (http://hakre.wordpress.com/2012/05/20/php-on-heroku-again/) nel caso Interessante. – hakre

+0

@hakre: la maggior parte degli stack usa nginx. Forse il buildpack di PHP fa qualcosa di diverso. – mipadi

8

I è stato in grado di utilizzare i file .htaccess su heroku con lo stack di cedro.

  1. Procfile necessità di specificare uno script per i nodi web:

    web: sh www/conf/web-boot.sh 
    
  2. I conf/web-boot.sh scie l'inclusione di un file di configurazione di Apache, ad esempio:

  3. Un conf/httpd/default.conf quindi può permettere override, come lo sai da apache.

È quindi possibile utilizzare solo i file .htaccess. L'intero processo è documentato in dettaglio nel mio post del blog PHP on Heroku again di cui una parte riguarda la configurazione di apache. Il passaggio in 2. compresa la propria configurazione httpd è fondamentalmente:

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 

Spero che questo sia utile. L'ho usato per .htaccess e per cambiare il webroot.

Problemi correlati