Actualmente estoy desarrollando mi primera aplicación web, frontend con React y backend con FastAPI .
Estoy tratando de probarlo junto con Chrome: ver si el frontend realiza las llamadas API correctas al backend y muestra los resultados. He tenido problemas con las cookies y me gustaría recibir ayuda. Disculpas de antemano por la publicación larga: he estado revisando muchos recursos en los últimos días y, en este momento, no estoy seguro de qué es relevante y qué no.
localhost:8080http://127.0.0.1:8000FastAPI : app = FastAPI() origins = [ "http://localhost:8080" ] app.add_middleware( CORSMiddleware, allow_origins=origins, allow_credentials=True, allow_methods=["*"], allow_headers=["*"], )
Situación: Frontend realiza una solicitud GET a http://127.0.0.1:8000/api/abc en el backend, el backend establece una cookie.
/*====================
Intento 1:
configure la cookie con el siguiente código de back-end:
response.set_cookie(key="abcCookieKey", value="abcCookieValue") y realice la solicitud GET con el siguiente código JS frontend:
fetch('http://127.0.0.1:8000/api/abc', { method: 'GET', credentials: 'include', }) Resultado con intento 1:
en la pestaña Console de Chrome, recibo la siguiente advertencia:
A cookie associated with a cross-site resource at http://127.0.0.1/ was set without the `SameSite` attribute. It has been blocked, as Chrome now only delivers cookies with cross-site requests if they are set with `SameSite=None` and `Secure`. You can review cookies in developer tools under Application>Storage>Cookies and see more details at https://www.chromestatus.com/feature/5088147346030592 and https://www.chromestatus.com/feature/5633521622188032. y en la pestaña de red recibo el siguiente mensaje al examinar el encabezado de respuesta set-cookie :
This Set-Cookie was blocked because it has the "SameSite=Lax" attribute but came from a cross-site response which was not the response to a top-level navigation.====================*/
...así que investigo un poco y se me ocurre
/*====================
Intento 2:
configure la cookie con el siguiente código de back-end:
response.set_cookie(key="abcCookieKey", value="abcCookieValue", samesite="none", secure=True) y realice la solicitud GET con el mismo código JS de interfaz.
Resultado con intento 2:
en la pestaña Console de Chrome, recibo exactamente la misma advertencia que en el intento 1, aunque el encabezado de respuesta tiene una set-cookie configurada con Samesite=none; Secure Además, el encabezado tiene la siguiente advertencia
This Set-Cookie was blocked because it had the "Secure" attribute but was not received over a secure connection.====================*/
..así que trato de usar https y se me ocurre:
/*====================
Intento 3: Todo lo mismo que el intento n.º 2, excepto que en mi código de búsqueda JS, uso fetch('https://127.0.0.1:8000/api/abc ...
y luego recibo la siguiente advertencia en mi backend que se ejecuta con uvicorn : WARNING: Invalid HTTP request received.
====================*/
Preguntas:
https , ¿cómo ejecuto localmente un servidor back-end al que se puede acceder con https ? La investigación que hice hizo que pareciera que era un proceso complicado/que consumía mucho tiempo. (Pero, para ser justos, mi comprensión de web-dev/all things network es muy limitada).Voy a tratar de dar el concepto.
Primero, tenga en cuenta que estoy usando un backend desarrollado a partir de SailsJS y un frontend desarrollado a partir de AngularJS y aplicaciones que se conectan al backend que se desarrollan a partir del uso de Angular9 .
Estoy usando una cookie solo de http para la interfaz (un CMS) para otorgar permiso para agregar contenido a los usuarios que han iniciado sesión. Se les establecerá una cookie solo de HTTP cuando la autenticación sea exitosa.
Tenga en cuenta que hay una parte complicada en las cookies http y que tanto el backend como el frontend sirven URL diferentes, como en el escenario presentado.
Puntos:
Entonces, cuando está en desarrollo, debe alojar su backend y frontend bajo la misma IP. ex. mi backend: 192.168.8.160:1337, frontend: 192.168.8.160:81. diferentes puertos misma ip.
este no es el escenario cuando va a producción, puede tener cualquier dominio :)
debe permitir CORS en el backend y tener su ip:port frontend en orígenes aceptados.
Implementación, tienes que identificar tu entorno, en mi caso,
if (sails.config.environment === 'development'){ res.setHeader('Set-Cookie',[`token=${token}; Path=/;HttpOnly; maxAge=86400000;SameSite=false;`]); } else { res.setHeader('Set-Cookie',[`token=${token}; Path=/;HttpOnly; maxAge=86400000;SameSite=None;Secure=true;`]); } Tenga en cuenta que en el código anterior en el entorno de desarrollo necesita SameSite=false , por lo tanto, debe tener la misma IP porque no podemos tener SameSite=None porque requeriría tener Secure=true y luego requeriría HTTPS. Sería un dolor de cabeza lograrlo en modo desarrollo.
Eso es todo amigos. Si lo haces bien, puedes lograrlo.
Puede deshabilitar completamente esta función yendo a "chrome://flags" y deshabilitando "Las cookies sin SameSite deben ser seguras". Sin embargo, esto lo deshabilitará para todos los sitios, por lo que será menos seguro cuando no estés desarrollando también.
Elimine los comodines ya que no se permiten comodines con allow_credentials=True :
app.add_middleware( CORSMiddleware, allow_origins=['http://localhost:8080'], allow_credentials=True, allow_methods=["GET", "POST", "OPTIONS"], /* include additional methods as per the application demand */ allow_headers=["Content-Type","Set-Cookie"], /* include additional headers as per the application demand */ ) Establezca samesite en none mientras configura la cookie (los navegadores modernos lo exigen):
/* `secure=True` is optional and used for secure https connections */ response.set_cookie(key='token_name', value='token_value', httponly=True, secure=True, samesite='none') Si el lado del cliente está usando Safari, deshabilite Prevent cros-site tracking en Preferences . ¡Eso es todo!