Hola amigos, al añadir validación de usuarios/manejo de sesiones a un Servidor Datasnap REST que estoy escribiendo me ha surgido un problema, y espero que me podáis sugerir alguna forma de atacarlo.
Los clientes acceden al servidor Datasnap mediante AngularJS, y como el servidor IIS que corre el módulo ISAPI del Datasnap y el servidor del front-end AngularJS se encuentran en equipos diferentes, el navegador identifica sus llamadas como CORS (Cross-Origin) y bloquea el envío del código de sesión en un Header Pragma.
El navegador sustituye el Header Pragma que envía Angular al servidor Datasnap con el correspondiente dssession (código de sesión), sustituyéndolo por un Header Access-Control-Request-Headers con el valor "Pragma" en una solicitud CORS Options (parece que lo llaman preflight). Datasnap no sabe como responder a ello y genera un "command closed or unassigned" TDSServiceException.
Al no ver ninguna solución, he intentado sortearlo, evitando el paso de esa sesión mediante un Header personalizado (que es lo que dispara la solicitud de permisos CORS), y enviando ese código de sesion directamente por la URL, capturandolo al entrar en el Datasnap y volviendo a poner manulamente ese código de sesión dentro de un Header Pragma para que Datasnap pueda manejar las sesiones con su mecanismo ya predefinido.
Para ello he modificado el evento WebModuleBeforeDispath :
procedure TWebModule1.WebModuleBeforeDispatch(Sender: TObject; Request: TWebRequest; Response: TWebResponse; var Handled: Boolean); var Token: string; begin Response.SetCustomHeader('Access-Control-Allow-Origin','*'); // Allow CORS calls Token := TIdHTTPAppRequest(Request).Query; // Set session on Pragma from the URL if Copy(Token, 1, 10) = 'dssession=' then begin TIdHTTPAppRequest(Request).GetRequestInfo.RawHeaders.AddValue('Pragma', Token); end; if FServerFunctionInvokerAction <> nil then FServerFunctionInvokerAction.Enabled := AllowServerFunctionInvoker; end;
Esto funciona bien en mi entorno de pruebas, como aplicación StandAlone. Pero cuando lo compilo como módulo ISAPI para ponerlo en el servidor de producción, parece que no construye correctamente esos headers Pragma con los códigos de sesión.
El caso es que no estoy muy seguro de donde está exactamente el problema, ya que no podido activar la depuración de ese módulo ISAPI, pero yo imagino que no recupera correctamente el código de sesión de la URL, no le debe aparece disponible en Request.Query (o Request.Content).
¿ Alguno de vosotros se ha tenido que pelear con algo parecido ?.
Gracias.