So I converted them over to an object and moved them to Cookies. I'm wondering now if this Miscellaneous is where my issue is residing. Here is the traffic capture from my recent attempt.
im not an expert at this but from what i see from the Postman screenshot you shared, one thing is for sure .. the session data shouldnt be under set-cookie
.. i dont think the server cares for that header.
In my first post i wasnt sure and was wondering about it also, if its ok to send them as array since they are received as array. This is something you have to experiment and maybe reconstact the structure of the msg.headers
exactly
Is it cookies
or cookie
see the exact format from Postman
Awesome, I'm making progress and I keep feeling like I'm almost right there. As for Cookies and Cookie, Postman is using both! Just moving the array and you're on point with cookies and cookie.
I am almost there with my function nodes. Got a weird issue with formatting changes happening.
{"cookie":["session=E8C35660-5156-44B3-8A6A-F5A0BD67A609; Secure; HttpOnly; Path=/;samesite=none","AV-Cookie=!BCHK/RfhaL34Pegueq1NBsctUyzZDiOSp9vAbd08KyqjaUBnaGmV7x98weYkt94vx23x7t9NfmP/wA==; path=/; Httponly; Secure;samesite=none","TS01a6bd37=01cf42f8a640d9025ba33f33a3ab25df22724046c21c28a88ce01cbd219e778164477c009541561b4e7f414838cfd3930e687aa5d05a27bc412d62ce43e47f378a4b80d802a7f5f571108fd8eb45f11375fcad5080; Path=/; Secure; HTTPOnly;samesite=none"],"Accept":"application/json"}
What on earth could cause this?
how on earth could we know .. if you havent shared your Function lol
Here is my attempt of a Function for the preparation of the Cookie header based on your previous msg posts
[{"id":"0e6409a24417cba4","type":"inject","z":"54efb553244c241f","name":"Logon","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"true","payloadType":"bool","x":190,"y":900,"wires":[["d3e31360ccb01a7f"]]},{"id":"d0ed84402cd854b3","type":"debug","z":"54efb553244c241f","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":710,"y":960,"wires":[]},{"id":"5a28f1fb184683a9","type":"function","z":"54efb553244c241f","name":"Logoff","func":"let session = \"\"\nlet avcookie = \"\"\nlet ts = \"\"\nlet newMsg = {} // clean new msg\n\n// filter cookies from previous reply \nmsg.headers[\"set-cookie\"].forEach(el => {\n\n if (el.startsWith(\"session=\")) session = el.split(\";\")[0]\n if (el.startsWith(\"AV-Cookie=\")) avcookie = el.split(\";\")[0]\n if (el.startsWith(\"TS01a6bd37=\")) ts = el.split(\";\")[0]\n})\n\nnewMsg.headers = {\n \"Cookie\": `${session}; ${avcookie}; ${ts};`,\n \"Accept\": \"application/json\"\n}\n\nreturn newMsg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":550,"y":960,"wires":[["d0ed84402cd854b3"]]},{"id":"d3e31360ccb01a7f","type":"function","z":"54efb553244c241f","name":"fake reply msg","func":"msg = {\n \"_msgid\": \"be53dbf48c4f43cd\",\n \"payload\": {\n \"version\": \"7.44.0\",\n \"session\": \"BCA37503-98D5-4F60-9707-ED4E806E4569\"\n }, \"topic\": \"\",\n \"headers\": {\n \"cache-control\":\n \"no-cache\",\n \"keep-alive\": \"timeout=5\",\n \"content-type\": \"application/json; charset=utf-8\",\n \"set-cookie\": [\n \"session=BCA37503-98D5-4F60-9707-ED4E806E4569; Secure; HttpOnly; Path=/;samesite=none\",\n \"AV-Cookie=!EZKCo6hbbsP3Gh4ueq1NBsctUyzZDnStWnnF14kSnhdWPVeCPF8yGfWqDL+x1lEhRQPML0/0TpX4irY=; path=/; Httponly; Secure;samesite=none\",\n \"TS01a6bd37=01cf42f8a6db393158b9a026eaef9d2e8ded77074a6080bc70f43c0aa2be2e36648f1ca4267d153e2e35dd27182d76c0fbabb2b2f819c77b04ab26a10d1db1490b95b9dd18079ea2ce6fda0825a76d38b976ae64c7; Path=/; Secure; HTTPOnly;samesite=none\"],\n \"date\": \"Fri, 25 Feb 2022 04:04:47 GMT\", \"content-length\": \"69\", \"x-frame-options\": \"SAMEORIGIN\", \"x-xss-protection\": \"1; mode=block\", \"x-content-type-options\": \"nosniff\", \"content-security-policy\": \"script-src 'unsafe-inline' 'unsafe-eval' 'self' https://*; object-src 'self'\", \"strict-transport-security\": \"max-age=16070400; includeSubDomains\", \"vary\": \"Accept-Encoding\"\n }, \"statusCode\": 200\n}\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":340,"y":900,"wires":[["5a28f1fb184683a9"]]},{"id":"75f84cb6e9108ab6","type":"comment","z":"54efb553244c241f","name":"... to http-request","info":"","x":740,"y":920,"wires":[]}]
ps. are those extra values like samesite, Httponly, Secure, path etc needed ? i think those values intended for the receiving client end and not needed to be passed on for the server side
There's no way for you to know. I'm actually trying to use the string node to strip them off. Here is my function.
msg.headers["cookie"] = msg.headers["set-cookie"]
msg.headers["Accept"] = 'application/json';
msg.headers = msg.headers || {};
delete msg.headers["content-type"];
delete msg.topic;
delete msg.statusCode;
delete msg.headers["cache-control"]
delete msg.headers["content-length"];
delete msg.headers["keep-alive"];
delete msg.headers.date;
delete msg.headers.connection
delete msg.headers["x-frame-options"]
delete msg.headers["x-xss-protection"]
delete msg.headers["x-content-type-options"]
delete msg.headers["content-security-policy"]
delete msg.headers["strict-transport-security"]
delete msg.headers.vary
delete msg.payload
delete msg.headers["x-node-red-request-node"]
delete msg.responseCookies
delete msg.redirectList
delete msg.retry
return msg;
Then I'm just using a change node to delete the [set-cookies] header after the function. Thanks for the help!
I made a modification since I had moved it to [cookie] and that worked!
Nice .. so keeping it as an array works ?
You dont have to use so many delete
you could create a new blank newMsg object like in my example code and return
that
Well, I spoke too soon. This service is so annoying. So the process works with a logon and logoff message but anything in between give a message of "session expired" regardless of passing the session information along.
Almost forgot, I took what you had along with the advice here and combined the function node into just one. It's working great except for that session expiration message on their side. Clearly something is going on, not sure if it's persistence or what. Here is the modification.
msg.headers = msg.headers || {};
msg.headers["cookie"] = msg.headers["set-cookie"]
delete msg.payload
let avcookie = ""
let session = ""
let ts = ""
let newMsg = {} // clean new msg
// filter cookies from previous reply
msg.headers["cookie"].forEach(el => {
if (el.startsWith("AV-Cookie=")) avcookie = el.split(";")[0]
if (el.startsWith("session=")) session = el.split(";")[0]
if (el.startsWith("TS01a6bd37=")) ts = el.split(";")[0]
})
newMsg.headers = {
"Cookie": `${avcookie}; ${session}; ${ts};`,
"Accept": "application/json"
}
delete msg.headers["set-cookie"]
return newMsg;
Might not be pretty but it is functionally working. Pretty sure my delete msg.payload is redundant which Iwll test. No more massive amounts of deletes, I've even used a delay to ensure the log off is sent. It works as well, so a logon and a delayed logoff work but the search calls give the session error. I've asked for clarification as I never did get api documentation naturally.
Thanks
I can't mark two solutions here but it was both Steve-MCL and UnborN that helped resolve this issue. I combined both of their works into one function.
Hello Mike .. Im glad you found some of the suggestions useful.
I wish we could be more helpful but it was little hard without more information on the workflow.
I can understand that sharing more on a public forum is difficult, especially when secure urls and login information are involved but you can create and share a parallel flow with the critical info like urls removed or share screenshots with some parts blurred. That would help us get a better understanding of the step by step requests that you are making.
I ended up creating a separate issue as this one was originally about the cookies which is working. I figured I would treat the new issue as a different. Here is my simple flow.
[
{
"id": "b2e8821d42299f17",
"type": "template",
"z": "5ad943f8d0b09431",
"name": "LogonTemplate",
"field": "payload",
"fieldType": "msg",
"format": "handlebars",
"syntax": "mustache",
"template": " {\n \"userid\": \"usernme\",\n \"password\": \"password\"\n }",
"output": "json",
"x": 120,
"y": 120,
"wires": [
[
"403a9d6fb72df06d"
]
]
},
{
"id": "ddaa1f7a92baad97",
"type": "debug",
"z": "5ad943f8d0b09431",
"name": "",
"active": true,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "true",
"targetType": "full",
"statusVal": "",
"statusType": "auto",
"x": 1190,
"y": 160,
"wires": []
},
{
"id": "167f3f7bfb7aba87",
"type": "debug",
"z": "5ad943f8d0b09431",
"name": "",
"active": true,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "true",
"targetType": "full",
"statusVal": "",
"statusType": "auto",
"x": 390,
"y": 60,
"wires": []
},
{
"id": "5a28f1fb184683a9",
"type": "function",
"z": "5ad943f8d0b09431",
"name": "MessageHandler",
"func": "msg.headers = msg.headers || {}; //Set headers to an object\nmsg.headers[\"cookie\"] = msg.headers[\"set-cookie\"] //Copy set-cookie to cookies\n//delete msg.payload //clear any payloads so as not to clog up the calls\nlet avcookie = \"\"\nlet session = \"\"\nlet ts = \"\"\nlet newMsg = {} // clean new msg\n\n// filter cookies from previous reply \nmsg.headers[\"cookie\"].forEach(el => {\n\n if (el.startsWith(\"AV-Cookie=\")) avcookie = el.split(\";\")[0]\n if (el.startsWith(\"session=\")) session = el.split(\";\")[0]\n if (el.startsWith(\"TS01a6bd37=\")) ts = el.split(\";\")[0]\n})\n\nnewMsg.headers = {\n \"Cookie\": `${avcookie}; ${session}; ${ts};`,\n \"Accept\": \"application/json\",\n \"accept-encoding\": \"gzip,deflate\",\n \"cache-control\": \"no-cache\",\n \"Content-Type\": \"application/json\",\n \"Connection\": \"close\"\n// \"keep-alive\": \"timeout=30\"\n}\ndelete msg.headers[\"set-cookie\"]\nreturn newMsg;",
"outputs": 1,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 490,
"y": 120,
"wires": [
[
"1787dfa6646bba5b",
"fb41946af529f767"
]
]
},
{
"id": "fb41946af529f767",
"type": "template",
"z": "5ad943f8d0b09431",
"name": "EventSearch",
"field": "payload",
"fieldType": "msg",
"format": "handlebars",
"syntax": "mustache",
"template": "{\n \"set\": {\n \"Search::object\": \"ts_ticket\",\n \"Search::search_history_type\": \"\",\n \"Search::page_size\": 10000,\n \"Search::extract_max_rows\": 10000,\n \"Query::max_rows\": \"\",\n \"Query::current_page\": 1,\n \"Query\": {\n \"ResultMember\": {\n \"+1\": {\n \"name\": \"Performance.performance_short_description\",\n \"order\": \"1\"\n },\n \"+2\": {\n \"name\": \"Performance.performance_name\",\n \"order\": \"2\"\n },\n \"+3\": {\n \"name\": \"Performance.performance_start_date\",\n \"order\": \"3\"\n },\n \"+6\": {\n \"name\": \"Performance.performance_id\",\n \"order\": \"6\"\n }\n },\n \"Clause\": {\n \"+1\": {\n \"name\": \"Performance.performance_start_date\",\n \"type\": \"matchCondition\",\n \"oper\": \">=\",\n \"value\": \"+0D\"\n },\n \"+2\": {\n \"name\": \"Performance.performance_start_date\",\n \"type\": \"matchCondition\",\n \"oper\": \"<=\",\n \"value\": \"+1D\"\n }\n }\n }\n },\n \"actions\": [\n {\n \"method\": \"search\",\n \"acceptWarnings\": [\n 4276\n ]\n }\n ],\n \"get\": [\n \"Result\",\n \"Query::current_page\",\n \"Query::total_records\"\n ]\n}",
"output": "json",
"x": 610,
"y": 260,
"wires": [
[
"7b6622956b4ef4d5",
"06cfca2776bcb35f"
]
]
},
{
"id": "9f0eeece93a66ab7",
"type": "inject",
"z": "5ad943f8d0b09431",
"name": "",
"props": [
{
"p": "payload"
},
{
"p": "topic",
"vt": "str"
}
],
"repeat": "",
"crontab": "",
"once": false,
"onceDelay": 0.1,
"topic": "",
"payload": "",
"payloadType": "date",
"x": 140,
"y": 60,
"wires": [
[
"b2e8821d42299f17"
]
]
},
{
"id": "1787dfa6646bba5b",
"type": "delay",
"z": "5ad943f8d0b09431",
"name": "",
"pauseType": "delay",
"timeout": "2",
"timeoutUnits": "seconds",
"rate": "1",
"nbRateUnits": "1",
"rateUnits": "second",
"randomFirst": "1",
"randomLast": "5",
"randomUnits": "seconds",
"drop": false,
"allowrate": false,
"outputs": 1,
"x": 760,
"y": 160,
"wires": [
[
"69cbe51dbb1c9c72"
]
]
},
{
"id": "e9e3cf998a319f51",
"type": "debug",
"z": "5ad943f8d0b09431",
"name": "",
"active": true,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "true",
"targetType": "full",
"statusVal": "",
"statusType": "auto",
"x": 1190,
"y": 260,
"wires": []
},
{
"id": "7b6622956b4ef4d5",
"type": "debug",
"z": "5ad943f8d0b09431",
"name": "",
"active": true,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "true",
"targetType": "full",
"statusVal": "",
"statusType": "auto",
"x": 590,
"y": 300,
"wires": []
},
{
"id": "403a9d6fb72df06d",
"type": "http request",
"z": "5ad943f8d0b09431",
"name": "LoginURL",
"method": "POST",
"ret": "obj",
"paytoqs": "query",
"url": "https://urlforlogin",
"tls": "",
"persist": true,
"proxy": "",
"authType": "",
"senderr": true,
"x": 280,
"y": 120,
"wires": [
[
"5a28f1fb184683a9",
"167f3f7bfb7aba87"
]
]
},
{
"id": "06cfca2776bcb35f",
"type": "http request",
"z": "5ad943f8d0b09431",
"name": "Search",
"method": "POST",
"ret": "obj",
"paytoqs": "query",
"url": "https://urlforsearch",
"tls": "",
"persist": false,
"proxy": "",
"authType": "",
"senderr": false,
"x": 840,
"y": 260,
"wires": [
[
"e9e3cf998a319f51"
]
]
},
{
"id": "69cbe51dbb1c9c72",
"type": "http request",
"z": "5ad943f8d0b09431",
"name": "Logoff",
"method": "POST",
"ret": "obj",
"paytoqs": "query",
"url": "https://urlforlogout",
"tls": "",
"persist": false,
"proxy": "",
"authType": "",
"senderr": false,
"x": 930,
"y": 160,
"wires": [
[
"ddaa1f7a92baad97"
]
]
}
]
My thought here was fairly straight forward. I can use the function to execute the two commands I needed to run and delay the logoff based on the results. It's odd, the login and logoff work without issue. It's just the other functions that give a "session expired" message on their end. Almost like they require everything to be one continuous event although they are separate requests. I might even resort to using Newman if I can figure out how to get the full output and use objects in the calls.
WOW, just wow. I totally overlooked the port definitions from their production server and test servers. I feel like a bonehead.
hehe .. and now its working ? no more "session expired" issues ? .. i was going through your other post and your flow .. looks good to me.
I wanted to ask whether the Logout request is necessary .. do you need it ? .. cant you just leave the session to timeout and be handled by the server (if it is handled)
Yeah it's working. Classic technical oversight.
Now I have to parse through 100+ objects in an array and use a specific value from each to do a search on each item against a credential. Fun times.
Trying to do this without a DB, need to create a list out of this mess pulling the 35 digit values. They look like this and are nested D62A621F-1ABF-46DB-A7F9-B5F646CAA95F. I need to pull them all out to use in separate calls for a lookup. Talk about biting off too much to chew.
{"state":"32","Performance.performance_short_description":{"standard":"What Do You Do With An Idea? School Performance","input":"","display":"What Do You Do With An Idea? School Performance"},"Performance.performance_name":{"standard":"WDY030122A","input":"","display":"WDY030122A"},"Performance.performance_start_date":{"standard":["2022-03-01T12:00:00.000"],"input":["3/1/22, 12:00 PM"],"display":["2022-03-01 12:00 PM"]},"Performance.performance_id":{"standard":"D62A621F-1ABF-46DB-A7F9-B5F646CAA95F","input":"","display":"D62A621F-1ABF-46DB-A7F9-B5F646CAA95F"}}
This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.