¿Por qué la cookie de sesión funciona cuando se sirve desde un dominio pero no cuando se usa una IP?

Tengo una aplicación Flask con sesiones que funciona bien en mi máquina de desarrollo local. Sin embargo, cuando trato de implementarlo en un servidor de Amazon, las sesiones no parecen funcionar.

Más específicamente, la cookie de sesión no está configurada. Puedo, sin embargo, configurar las cookies normales. Me aseguré de tener una clave de seguridad estática, ya que otros han indicado que podría ser un problema. La única diferencia está en cómo se configura el servidor. Durante el desarrollo, utilizo

app.run() 

para ejecutar localmente. Cuando desplegado, uso

 app.config['SERVER_NAME'] = '12.34.56.78' # <-- insert a "real" IP app.run(host='0.0.0.0', port=80) 

Sospecho que el problema podría estar en lo anterior, pero no estoy completamente seguro.

La sesión parece funcionar en Firefox, pero no en Chrome.

La siguiente aplicación pequeña demuestra el problema, con las diferencias de configuración en la parte inferior:

 from flask import Flask, make_response, request, session app = Flask(__name__) app.secret_key = 'secretKey' # this is to verify that cookies can be set @app.route('/setcookie') def set_cookie(): response = make_response('Cookie set') response.set_cookie('cookie name', 'cookie value') return response @app.route('/getcookie') def get_cookie(): if 'cookie name' in request.cookies: return 'Cookie found. Its value is %s.' % request.cookies['cookie name'] else: return 'Cookie not found' # this is to check if sessions work @app.route('/setsession') def set_session(): session['session name'] = 'session value' return 'Session set' @app.route('/getsession') def get_session(): if 'session name' in session: return 'Session value is %s.' % session['session name'] else: return 'Session value not found' if __name__ == '__main__': app.debug = True # windows, local development #app.run() # Ubuntu app.config['SERVER_NAME'] = '12.34.56.78' # <-- insert a "real" IP app.run(host='0.0.0.0', port=80) 

Este es un “error” en Chrome, no es un problema con su aplicación. (También puede afectar a otros navegadores si cambian sus políticas).

RFC 2109 , que describe cómo se manejan las cookies, parece indicar que los dominios de cookies deben ser un FQDN con un TLD (.com, .net, etc.) o una dirección IP de coincidencia exacta. La especificación de cookie original de Netscape no menciona las direcciones IP en absoluto.

Los desarrolladores de Chrome han decidido ser más estrictos que otros navegadores sobre qué valores aceptan para los dominios de cookies. Si bien en un momento corrigieron un error que impedía las cookies en las direcciones IP, aparentemente han dado marcha atrás desde entonces y no permiten cookies en dominios que no son FQDN (incluido el host local) o direcciones IP. Han declarado que no solucionarán esto, ya que no lo consideran un error.

La razón por la que las cookies “normales” están funcionando pero la cookie de sesión no lo es es que no está configurando un dominio para las cookies “normales” (es un parámetro opcional), pero Flask establece automáticamente el dominio para la cookie de sesión en SERVER_NAME . Chrome (y otros) aceptan cookies sin dominios y las configura automáticamente en el dominio de la respuesta, de ahí la diferencia observada en el comportamiento. Puede observar las cookies normales que fallan si configura el dominio a la dirección IP.

Durante el desarrollo, puede solucionar esto ejecutando la aplicación en localhost en lugar de dejarla predeterminada en 127.0.0.1. Flask tiene una solución alternativa que no enviará el dominio para la cookie de sesión si el nombre del servidor es localhost. app.run('localhost')

En producción, no hay soluciones reales. Podría servir esto en un dominio en lugar de en una IP, lo que lo resolvería pero podría no ser posible en su entorno. Podría exigir que todos sus clientes usen algo además de Chrome, lo cual no es práctico. O podría proporcionar una interfaz de sesión diferente a Flask que haga la misma solución para las IP que ya utiliza para el host local, aunque esto probablemente sea inseguro de alguna manera.

Chrome no permite cookies con IP para el dominio, y no hay una solución práctica.

Tenga en cuenta que en la solución para localhost que @davidism publicó – https://github.com/mitsuhiko/flask/blob/master/flask/sessions.py#L211-L215 , puede parchear el código del Frasco y cambiar if rv == '.localhost': rv = None a simplemente rv = None y luego el dominio de cookies no se configurará y sus cookies funcionarán.

No querría hacer esto en una aplicación de producción real, pero si su servidor es solo un tipo de servidor de prueba / ensayo sin datos confidenciales, podría estar bien. Simplemente hice esto para probar una aplicación a través de una LAN en una dirección 192.168.xx y estaba bien para ese propósito.

Es posible crear una sesión en el navegador Chrome usando IP.

Mi archivo de configuración tiene estas configuraciones:

  SERVER_NAME = '192.168.0.6:5000' SESSION_COOKIE_DOMAIN = '192.168.0.6:5000' 

Me permitió usar una máquina virtual local y la cookie funcionó perfectamente en Chrome, sin la necesidad de un FQDN local.