I need to do a HTTPS POST request with digest authentication.
Found this on Github - DigestAuthorization.ino
So I incorporated it in my script and it works.
However, in the example script two HTTP requests are made which is one too many IMO - it makes it sluggish at times:
// configure traged server and url
http.begin(client, String(server) + String(uri)); // ONE HERE
const char* keys[] = { "WWW-Authenticate" };
http.collectHeaders(keys, 1);
Serial.print("[HTTP] GET...\n");
// start connection and send HTTP header
int httpCode = http.GET();
if (httpCode > 0) {
String authReq = http.header("WWW-Authenticate");
Serial.println(authReq);
String authorization = getDigestAuth(authReq, String(username), String(password), "GET", String(uri), 1);
http.end();
http.begin(client, String(server) + String(uri)); // ONE HERE
http.addHeader("Authorization", authorization);
int httpCode = http.GET();
if (httpCode > 0) {
String payload = http.getString();
Serial.println(payload);
} else {
Serial.printf("[HTTP] GET... failed, error: %s\n", http.errorToString(httpCode).c_str());
}
} else {
Serial.printf("[HTTP] GET... failed, error: %s\n", http.errorToString(httpCode).c_str());
}
http.end();
The first request returns 401 and the second one returns 200 which looks odd but apparently is to be expected, as per the wiki:
This typical transaction consists of the following steps:
- The client asks for a page that requires authentication but does not provide a username and password.[note 2] Typically this is because the user simply entered the address or followed a link to the page.
- The server responds with the 401 "Unauthorized" response code, providing the authentication realm and a randomly generated, single-use value called a nonce.
- At this point, the browser will present the authentication realm (typically a description of the computer or system being accessed) to the user and prompt for a username and password. The user may decide to cancel at this point.
- Once a username and password have been supplied, the client re-sends the same request but adds an authentication header that includes the response code.
- In this example, the server accepts the authentication and the page is returned. If the username is invalid and/or the password is incorrect, the server might return the "401" response code and the client would prompt the user again.
What concerns me is this:
"The client asks for a page that requires authentication but does not provide a username and password."
I do want to provide username and password right away. To me it sounds like if I did I would have to only make a single request instead of sending one without auth and right away a second with auth.
Do I really have to keep it split into two HTTP requests or is there a way to authenticate with a single request? Or is there a way to authenticate once (eg in setup()
) and then only send a single request until the board is reset? (this seems to be the way... at least as per ChatGPT - more below)
The concern here is speed.