As a countermeasure to prevent Cross-Site Request Forgeries (CSRF), the Ardexa API requires a CSRF token be submitted with any request that modifies data, e.g. POST.
Two cookies are provided by the API for any request: connect.sid and XSRF-TOKEN. The CSRF token, XSRF-TOKEN, must be passed as an HTTP header, X-XSRF-TOKEN, for any POST, PUT or DELETE operation.
Usage
Here are three examples of fetching and using a CSRF token in Linux shell, Javascript and Python. All three are command line tool that read the TOKEN from the environment and take two arguments: the workgroup ID and the name of the new device, e.g.
#!/bin/sh# $TOKEN is imported from the environment, it is the API tokenardexa_cloud=app.ardexa.comarch="Linux 64 bit (x86_64)"workgroup_id=$1device_name=$2# Needs an XSRF token to use POSTxsrf_token=$(curl -s --cookie-jar /tmp/ardexa-cookie.txt -i https://$ardexa_cloud/api/v1/version | grep '^set-cookie: XSRF-TOKEN' | sed -e 's/.*TOKEN=\([^;]*\).*/\1/' -e 's/%2f/\//gi' -e 's/%2b/+/gi' -e 's/%3d/=/gi')
# Create the agentcurl -s -H "X-XSRF-TOKEN: $xsrf_token" -H "authorization: Bearer $TOKEN" -H "content-type: application/json" --cookie /tmp/ardexa-cookie.txt -X POST --output /tmp/agent-sh.zip "https://$ardexa_cloud/api/v1/devices/$workgroup_id" -d "{\"name\": \"$device_name\", \"arch\": \"$arch\"}"
echo"Agent zip file can be found at /tmp/agent-sh.zip"
Javascript
import { writeFileSync } from'node:fs';import got from'got';import {CookieJar} from'tough-cookie';constardexaCloud='app.ardexa.com'constarch='Linux 64 bit (x86_64)'constworkgroupId=process.argv[2]constdeviceName=process.argv[3]functiongetXsrf (cookieJar) {constcookies=cookieJar.getCookiesSync(`https://${ardexaCloud}`)for (constcookieof cookies) {if (cookie.key ==='XSRF-TOKEN') returndecodeURIComponent(cookie.value) }thrownewError('Failed to find XSRF token')}asyncfunctionmain () {constcookieJar=newCookieJar();constclient=got.extend({ cookieJar });awaitclient.get(`https://${ardexaCloud}/api/v1/version`);constxsrf=getXsrf(cookieJar)constres=awaitclient.post(`https://${ardexaCloud}/api/v1/devices/${workgroupId}`, { headers: {'X-XSRF-TOKEN': xsrf, authorization:`bearer ${process.env.TOKEN}` }, json: { name: deviceName, arch } });writeFileSync('/tmp/agent-js.zip',res.rawBody)console.log('Agent zip file can be found at /tmp/agent-js.zip')}main()
Python
import sysimport osimport requestsardexa_cloud ='app.ardexa.com'arch ='Linux 64 bit (x86_64)'workgroup_id = sys.argv[1]device_name = sys.argv[2]s = requests.Session()s.get(f'https://{ardexa_cloud}/api/v1/version');xsrf = requests.utils.unquote(s.cookies.get_dict().get('XSRF-TOKEN'))headers ={'X-XSRF-TOKEN': xsrf,'authorization':f'bearer {os.environ["TOKEN"]}'}json ={'name': device_name,'arch': arch}r = s.post(f'https://{ardexa_cloud}/api/v1/devices/{workgroup_id}', headers=headers, json=json)withopen('/tmp/agent-py.zip', 'wb')as f: f.write(r.content)print('Agent zip file can be found at /tmp/agent-py.zip')