I have a DJango webserver which requires CSRF verification. I would like to send a POST request to this server, but I cannot pass the CSRF verification step.
My code:
#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
#include <WiFiClient.h>
#include <Arduino_JSON.h>
const char* ssid = "my_ssid";
const char* password = "my_pw";
//Your Domain name with URL path or IP address with path
const char* serverName = "base_https_website";
// the following variables are unsigned longs because the time, measured in
// milliseconds, will quickly become a bigger number than can be stored in an int.
unsigned long lastTime = 0;
// Timer set to 10 minutes (600000)
//unsigned long timerDelay = 600000;
// Set timer to 5 seconds (5000)
unsigned long timerDelay = 5000;
String sensorReadings;
float sensorReadingsArr[3];
void setup() {
Serial.begin(115200);
WiFi.begin(ssid, password);
Serial.println("Connecting");
while(WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.print("Connected to WiFi network with IP Address: ");
Serial.println(WiFi.localIP());
Serial.println("Timer set to 5 seconds (timerDelay variable), it will take 5 seconds before publishing the first reading.");
}
void loop() {
// Send an HTTP POST request depending on timerDelay
if ((millis() - lastTime) > timerDelay) {
//Check WiFi connection status
if(WiFi.status()== WL_CONNECTED){
sensorReadings = httpGETRequest(serverName);
Serial.println(sensorReadings);
JSONVar myObject = JSON.parse(sensorReadings);
// JSON.typeof(jsonVar) can be used to get the type of the var
if (JSON.typeof(myObject) == "undefined") {
Serial.println("Parsing input failed!");
return;
}
Serial.print("JSON object = ");
Serial.println(myObject);
// myObject.keys() can be used to get an array of all the keys in the object
JSONVar keys = myObject.keys();
for (int i = 0; i < keys.length(); i++) {
JSONVar value = myObject[keys[i]];
Serial.print(keys[i]);
Serial.print(" = ");
Serial.println(value);
sensorReadingsArr[i] = double(value);
}
}
else {
Serial.println("WiFi Disconnected");
}
lastTime = millis();
}
}
String httpGETRequest(const char* serverName) {
WiFiClientSecure client;
client.setInsecure();
HTTPClient http;
const char * headerkeys[] = {"Set-Cookie"} ;
size_t headerkeyssize = sizeof(headerkeys)/sizeof(char*);
// Your IP address with path or Domain name with URL path
http.begin(client, serverName);
//http.addHeader("Content-Type", "Content-Type: application/json");
http.collectHeaders(headerkeys,headerkeyssize);
int httpResponseCode = http.GET(); //Send the actual POST request
// Serial.printf("Header count: %d\r\n", http.headers());
// for (int i=0; i < http.headers(); i++) {
// Serial.printf("%s = %s\r\n", http.headerName(i).c_str(), http.header(i).c_str());
// }
// Serial.printf("Cookie: %s\r\n", http.header("Cookie").c_str());
Serial.printf("Set-Cookie: %s\r\n", http.header("Set-Cookie").c_str());
String csrf_token = http.header("Set-Cookie").substring(10, 74);
http.end();
HTTPClient http2;
http2.begin(client, "server_subdomain_address");
http2.addHeader("Content-Type", "application/json");
http2.addHeader("X-CSRFToken", csrf_token);
String jsondata=("{\"my_data_key\": \"my_data_value\"}");
Serial.println(jsondata);
String payload = "{}";
httpResponseCode = http2.POST(jsondata); //Send the actual POST request
if (httpResponseCode>0) {
Serial.print("HTTP Response code: ");
Serial.println(httpResponseCode);
payload = http.getString();
}
else {
Serial.print("Error code: ");
Serial.println(httpResponseCode);
}
// Free resources
http2.end();
return payload;
}
I get a CSRF verification error:
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<meta name="robots" content="NONE,NOARCHIVE">
<title>403 Forbidden</title>
<style type="text/css">
html * { padding:0; margin:0; }
body * { padding:10px 20px; }
body * * { padding:0; }
body { font:small sans-serif; background:#eee; color:#000; }
body>div { border-bottom:1px solid #ddd; }
h1 { font-weight:normal; margin-bottom:.4em; }
h1 span { font-size:60%; color:#666; font-weight:normal; }
#info { background:#f6f6f6; }
#info ul { margin: 0.5em 4em; }
#info p, #summary p { padding-top:10px; }
#summary { background: #ffc; }
#explanation { background:#eee; border-bottom: 0px none; }
</style>
</head>
<body>
<div id="summary">
<h1>Forbidden <span>(403)</span></h1>
<p>CSRF verification failed. Request aborted.</p>
<p>You are seeing this message because this site requires a CSRF cookie when submitting forms. This cookie is required for security reasons, to ensure that your browser is not being hijacked by third parties.</p>
<p>If you have configured your browser to disable cookies, please re-enable them, at least for this site, or for “same-origin” requests.</p>
</div>
<div id="explanation">
<p><small>More information is available with DEBUG=True.</small></p>
</div>
</body>
</html>
Parsing input failed!
What am I doing wrong?