Versione corta: verifica che il fuso orario è UTC/GMT:
if not 'ORIGINAL_TIMEZONE' in os.environ:
f = os.popen('date +%Z')
tz = f.read().upper()
os.environ['ORIGINAL_TIMEZONE']=tz
tz = os.environ['ORIGINAL_TIMEZONE']
if tz != '' and (not 'utc' in tz.lower()) and (not 'gmt' in tz.lower()):
print 'Definitely not running on Heroku (or in production in general)'
else:
print 'Assume that we are running on Heroku (or in production in general)'
Questo è più prudente di if tz=='UTC\n'
: in caso di dubbio, supporre che siamo in produzione. Si noti che stiamo salvando il fuso orario in una variabile di ambiente perché settings.py
può essere eseguito più di una volta. Infatti, il server di sviluppo lo esegue due volte, e la seconda volta che il fuso orario del sistema è già 'UTC' (o qualsiasi cosa sia in settings.TIMEZONE
).
Versione lunga:
facendo assolutamente sicuri che non abbiamo mai eseguito su Heroku con DEBUG=True
, e che non abbiamo mai eseguire il server di sviluppo su Heroku anche con DEBUG=False
. Da settings.py
:
RUNNING_DEV_SERVER = (len(sys.argv) > 1) and (sys.argv[1] == 'runserver')
DEBUG = RUNNING_DEV_SERVER
TEMPLATE_DEBUG = DEBUG
# Detect the timezone
if not 'ORIGINAL_TIMEZONE' in os.environ:
f = os.popen('date +%Z')
tz = f.read().upper()
os.environ['ORIGINAL_TIMEZONE']=tz
print ('DEBUG: %d, RUNNING_DEV_SERVER: %d, system timezone: %s ' % (DEBUG, RUNNING_DEV_SERVER, tz))
if not (DEBUG or RUNNING_DEV_SERVER):
SECRET_KEY = os.environ['SECRET_KEY']
else:
print 'Running in DEBUG MODE! Hope this is not in production!'
SECRET_KEY = 'DEBUG_INSECURE_SECRET_KEY_ae$kh(7b%$+a fcw_bdnzl#)$t88x7h2-p%eg_ei5m=w&2p-)1+'
# But what if we are idiots and are still somehow running with DEBUG=True in production?!
# 1. Make sure SECRET_KEY is not set
assert not SECRET_KEY in os.environ
# 2. Make sure the timezone is not UTC or GMT (indicating production)
tz = os.environ['ORIGINAL_TIMEZONE']
assert tz != '' and (not 'UTC' in tz) and (not 'GMT' in tz)
# 3. Look for environment variables suggesting we are in PROD
for key in os.environ:
for red_flag in ['heroku', 'amazon', 'aws', 'prod', 'gondor']:
assert not red_flag in key.lower()
assert not red_flag in os.environ[key].lower()
Se davvero si vuole eseguire il server di sviluppo su Heroku, ti suggerisco di aggiungere una variabile di ambiente che specifica la data in cui è possibile farlo. Quindi procedi solo se questa data è oggi. In questo modo dovrai modificare questa variabile prima di iniziare il lavoro di sviluppo, ma se dimentichi di disinserirlo, il giorno successivo sarai comunque protetto dalla sua esecuzione accidentale in produzione. Naturalmente, se vuoi essere super-conservatore, puoi anche specificare, ad esempio, una finestra di 1 ora quando si applicano le eccezioni.
Infine, se avete deciso di adottare l'approccio suggerito sopra, mentre si è in esso, installare anche django-sicurezza, aggiungere djangosecurity
-INSTALLED_APPS
, e aggiungere alla fine del vostro settings.py
:
if not (DEBUG or RUNNING_DEV_SERVER):
### Security
SECURE_SSL_REDIRECT = True
SECURE_CONTENT_TYPE_NOSNIFF = True
SECURE_HSTS_SECONDS = 86400000
SECURE_HSTS_INCLUDE_SUBDOMAINS = True
SECURE_BROWSER_XSS_FILTER = True
SESSION_COOKIE_SECURE = True
SESSION_COOKIE_HTTPONLY = True
CSRF_COOKIE_HTTPONLY = True # May have problems with Ajax
CSRF_COOKIE_SECURE = True
Grazie, non avevo notato che è possibile impostare in questo modo ancora variabili d'ambiente. Questo sembra il modo giusto per farlo. – aviraldg
scorciatoia: on_heroku = 'DYNO' in os.environ –
NON utilizzare on_heroku = 'DYNO' in os.environ come suggerito da tinchou. Quella variabile d'ambiente non è impostata durante determinate azioni buildpack, come quando collectstatic viene eseguito automaticamente per una build di django. Questo è quasi impossibile eseguire il debug - stai molto meglio usando la soluzione di cui sopra. – patr1ck