Asegure sus cookies
En settings.py ponga las líneas
SESSION_COOKIE_SECURE = True
CSRF_COOKIE_SECURE = True
y las cookies solo se enviarán a través de conexiones HTTPS. Además, probablemente también desee SESSION_EXPIRE_AT_BROWSER_CLOSE=True
. Tenga en cuenta que si está utilizando versiones anteriores de django (menos de 1.4), no hay una configuración para cookies CSRF seguras. Como solución rápida, puede hacer que la cookie CSRF esté segura cuando la cookie de sesión sea segura ( SESSION_COOKIE_SECURE=True
), editando django/middleware/csrf.py
:
class CsrfViewMiddleware(object):
...
def process_response(self, request, response):
...
response.set_cookie(settings.CSRF_COOKIE_NAME,
request.META["CSRF_COOKIE"], max_age = 60 * 60 * 24 * 7 * 52,
domain=settings.CSRF_COOKIE_DOMAIN,
secure=settings.SESSION_COOKIE_SECURE or None)
Solicitudes HTTP directas a HTTPS en el servidor web
A continuación, desea una regla de reescritura que redirija las solicitudes http a https, por ejemplo, en nginx
server {
listen 80;
rewrite ^(.*) https://$host$1 permanent;
}
La función reverse
de Django y las etiquetas de la plantilla url solo devuelven enlaces relativos; por lo tanto, si se encuentra en una página https, sus enlaces lo mantendrán en el sitio https.
Establezca la variable de entorno del sistema operativo HTTPS en onhh>
Finalmente, (y mi respuesta original lo excluyó), debe habilitar la variable ambiental del sistema operativo HTTPS
a 'on'
para que django anteponga https a los enlaces completamente generados (por ejemplo, como con HttpRedirectRequest
s). Si está utilizando mod_wsgi, puede agregar la línea:
os.environ['HTTPS'] = "on"
a su secuencia de comandos wsgi . Si está utilizando uwsgi, puede agregar una variable de entorno con el interruptor de línea de comando --env HTTPS=on
o agregando la línea env = HTTPS=on
a su archivo uwsgi .ini
. Como último recurso, si nada más funciona, puede editar su archivo de configuración para que tenga las líneas import os
y os.environ['HTTPS'] = "on"
, que también deberían funcionar.
Si está utilizando wsgi, es posible que desee configurar adicionalmente la variable de entorno wsgi.url_scheme
a 'https'
agregando esto a su settings.py
:
os.environ['wsgi.url_scheme'] = 'https'
El consejo de wsgi es cortesía de Comentario de Vijayendra Bapte .
Puede ver la necesidad de esta variable de entorno leyendo django/http/__init__.py
:
def build_absolute_uri(self, location=None):
"""
Builds an absolute URI from the location and the variables available in
this request. If no location is specified, the absolute URI is built on
''request.get_full_path()''.
"""
if not location:
location = self.get_full_path()
if not absolute_http_url_re.match(location):
current_uri = '%s://%s%s' % (self.is_secure() and 'https' or 'http',
self.get_host(), self.path)
location = urljoin(current_uri, location)
return iri_to_uri(location)
def is_secure(self):
return os.environ.get("HTTPS") == "on"
Cosas adicionales del servidor web:
Tome el consejo de ese chico y active los encabezados HSTS en su servidor web agregando una línea a nginx:
add_header Strict-Transport-Security max-age=31536000;
Esto le indica a su navegador web que su sitio web durante los próximos 10 años usará solo HTTPS. Si hay algún ataque Man-in-the-middle en una visita futura desde el mismo navegador (por ejemplo, inicia sesión en un enrutador malicioso en una cafetería que lo redirige a una versión HTTP de la página), su navegador recordará se supone que debe ser solo HTTPS y le impide entregar inadvertidamente su información. Pero tenga cuidado con esto, no puede cambiar de opinión y luego decidir que parte de su dominio se servirá a través de HTTP (hasta que pasen los 10 años desde que eliminó esta línea). Así que planea con anticipación; por ejemplo, si cree que su aplicación pronto crecerá en popularidad y deberá estar en un CDN grande que no maneja bien el HTTPS a un precio que puede pagar, puede tener un problema.
También asegúrate de desactivar los protocolos débiles. Envíe su dominio a una SSL Test para verificar posibles problemas (clave demasiado corta, no usar TLSv1.2, usar protocolos rotos, etc.). Por ejemplo, en nginx uso:
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_ciphers "EECDH+ECDSA+AESGCM EECDH+aRSA+AESGCM EECDH+ECDSA+SHA384 EECDH+ECDSA+SHA256 EECDH+aRSA+SHA384 EECDH+aRSA+SHA256 EECDH+aRSA+RC4 EECDH EDH+aRSA RC4 !aNULL !eNULL !LOW !3DES !MD5 !EXP !PSK !SRP !DSS";