Con fines de prueba, se configuran dos aplicaciones web, una aplicación de "cliente" (localhost) y una aplicación de servidor (aplicación web de Azure). El cliente envía una solicitud AJAX al servidor y recibe una cookie en respuesta. Luego hace otra llamada AJAX al servidor, pero no hay ninguna cookie en la solicitud, falta.
Aquí está la configuración del servidor (configuración de CORS; https://localhost:44316 es mi URL de "cliente"):
public class Startup { public Startup(IConfiguration configuration) { Configuration = configuration; } public IConfiguration Configuration { get; } public void ConfigureServices(IServiceCollection services) { services.AddCors(o => { o.AddPolicy("policy1", builder => builder.WithOrigins("https://localhost:44316") .AllowAnyMethod() .AllowAnyHeader() .AllowCredentials()); }); services.AddControllers(); } public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { app.UseHttpsRedirection(); app.UseRouting(); app.UseCors("policy1"); app.UseAuthorization(); app.UseEndpoints(endpoints => { endpoints.MapControllers(); }); } }Aquí está el primer controlador, devolviendo la cookie:
[Route("api/[controller]")] [ApiController] public class AController : ControllerBase { [HttpPost] public IActionResult Post() { var cookieOptions = new CookieOptions { HttpOnly = true, Expires = DateTime.Now.AddMinutes(10), SameSite = SameSiteMode.None }; Response.Cookies.Append("mykey", "myvalue", cookieOptions); return Ok(); } }Aquí está el segundo controlador, que debería recibir la cookie (pero no la recibe):
[Route("api/[controller]")] [ApiController] public class BController : ControllerBase { [HttpPost] public IActionResult Post() { var x = Request.Cookies; return Ok(JsonConvert.SerializeObject(x)); } }Y aquí está el script de llamada del "cliente" (primera y segunda llamada, respectivamente):
function Go() { $.ajax({ url: 'https://somewebsite.azurewebsites.net/api/a', type: 'post', xhrFields: { withCredentials: true }, success: function (data, textStatus, jQxhr) { console.log(data); }, error: function (jqXhr, textStatus, errorThrown) { console.log(errorThrown); } }); } function Go2() { $.ajax({ url: 'https://somewebsite.azurewebsites.net/api/b', type: 'post', xhrFields: { withCredentials: true }, success: function (data, textStatus, jQxhr) { console.log(data); }, error: function (jqXhr, textStatus, errorThrown) { console.log(errorThrown); } }); }¿Alguien tiene una idea de cuál podría ser el problema aquí?
Como decía este documento :
Las cookies que afirman SameSite=None también deben marcarse como seguras
Pero no lo hiciste, así que usa esto en su lugar:
var cookieOptions = new CookieOptions { HttpOnly = true, Expires = DateTime.Now.AddMinutes(10), SameSite = SameSiteMode.None, Secure = true };Y este es el resultado de mi prueba:
Primero debe conocer AddTransient , AddScoped y AddSingleton. La publicación a continuación será útil para usted.
Diferencias de los servicios AddTransient, AddScoped y AddSingleton
Y necesita usar AddSingleton , y obtendrá el valor de la cookie por clave.
Blogs oficiales: Cómo trabajar con cookies en ASP.NET Core
Funciona para mí, puede encontrar un código de muestra en los blogs que proporcioné.
1. código de prueba
2. resultado de la prueba en otro controlador.
Me gusta bastante el estilo de lo que está haciendo aquí en términos de un SPA que obtiene cookies de una API. Algunas recomendaciones a continuación, basadas en la experiencia en el tratamiento de estos problemas.
PROBLEMA
Está llamando desde el navegador a una API en un dominio diferente, lo que significa que la cookie es de un tercero y los navegadores modernos la soltarán agresivamente.
SameSite=None es la solución teórica de los documentos estándar, pero estos a menudo no explican el comportamiento actual del navegador:
Secure , como dice Jason PanSOLUCIÓN
La opción preferida es diseñar dominios de hospedaje para que solo se utilicen cookies first party , y muchas empresas de software lo han hecho. Se puede hacer ejecutando la API en un dominio secundario o hermano del origen web:
En una PC de desarrollador, puede hacer esto simplemente actualizando su archivo de hosts. Tenga en cuenta también que puede ejecutar componentes web y API en diferentes puertos y seguirán siendo el mismo sitio:
127.0.0.1 localhost www.example.com api.example.com :1 localhost El navegador seguirá realizando solicitudes CORS, pero considerará que la cookie emitida por la API se encuentra en el mismo sitio que el origen web. A continuación, también puede cambiar la configuración de las cookies para usar SameSite=strict , para mayor seguridad.
INFORMACION ADICIONAL
En Curity, hemos publicado algunos artículos recientes sobre seguridad web que están estrechamente relacionados con su pregunta, ya que las cookies seguras utilizadas en la seguridad de OpenID Connect también han tenido que lidiar con problemas de cookies descartadas: