-
Notifications
You must be signed in to change notification settings - Fork 13.3k
Adds digest authentication example. #4112
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
f48a5e6
4b69085
8a35dce
f00654d
f6ae2b6
13ea6e1
2d0b6eb
b154985
34a3e86
f6e8cf7
1d0eadf
857f992
ec398bf
40904f4
cffefde
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,117 @@ | ||
#include <ESP8266WiFi.h> | ||
#include <ESP8266WiFiMulti.h> | ||
|
||
#include <ESP8266HTTPClient.h> | ||
|
||
#define USE_SERIAL Serial | ||
|
||
ESP8266WiFiMulti WiFiMulti; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do we really need to use |
||
|
||
String _exractParam(String& authReq, const String& param, const char delimit){ | ||
int _begin = authReq.indexOf(param); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please load this sketch into Arduino IDE and use Tools > Auto Format feature to fix the indentation. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Also, it is not a common practice to prefix function and field names with an underscore, when not implementing class members, at least in Arduino. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The comment about reformatting the sketch using Arduino IDE is still valid, by the way. Arduino sketches use 2 spaces for indentation, this file uses tabs. |
||
if (_begin==-1) return ""; | ||
return authReq.substring(_begin+param.length(),authReq.indexOf(delimit,_begin+param.length())); | ||
} | ||
|
||
void setup() { | ||
|
||
USE_SERIAL.begin(9600); | ||
// USE_SERIAL.setDebugOutput(true); | ||
|
||
USE_SERIAL.println(); | ||
USE_SERIAL.println(); | ||
USE_SERIAL.println(); | ||
|
||
for(uint8_t t = 4; t > 0; t--) { | ||
USE_SERIAL.printf("[SETUP] WAIT %d...\n", t); | ||
USE_SERIAL.flush(); | ||
delay(1000); | ||
} | ||
|
||
WiFi.mode(WIFI_STA); | ||
WiFiMulti.addAP("Niligo-Prism-yyr9uma", ""); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You might want to replace this with something generic, e.g. |
||
|
||
} | ||
|
||
void loop() { | ||
// wait for WiFi connection | ||
if((WiFiMulti.run() == WL_CONNECTED)) { | ||
|
||
HTTPClient http; | ||
|
||
USE_SERIAL.print("[HTTP] begin...\n"); | ||
// configure traged server and url | ||
|
||
|
||
// http.begin("http://admin:[email protected]/api/state?power=1"); | ||
http.begin("http://192.168.100.1/api/state?power=0"); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Perhaps a URL of an existing service can be used? For example, http://httpbin.org/ has a test endpoint which accept Digest Auth ( There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That's awesome thanks, I will use it. 🙌 |
||
/* | ||
// or | ||
// or | ||
http.begin("http://192.168.1.12/test.html"); | ||
http.setAuthorization("dXNlcjpwYXN3b3Jk"); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Perhaps a comment could be added explaining the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I must remove them, we do not need them anymore. |
||
*/ | ||
|
||
|
||
const char *keys[] = {"WWW-Authenticate", "Server", "Connection"}; | ||
http.collectHeaders(keys, 3); | ||
|
||
USE_SERIAL.print("[HTTP] GET...\n"); | ||
// start connection and send HTTP header | ||
int httpCode = http.GET(); | ||
|
||
if (httpCode > 0) { | ||
String authReq = http.header("WWW-Authenticate"); | ||
USE_SERIAL.println(authReq); | ||
|
||
// file found at server | ||
String payload = http.getString(); | ||
USE_SERIAL.println(payload); | ||
|
||
String username = "admin"; | ||
String password = "admin"; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. These might also need to be moved to the top of the sketch, together with wifi SSID/password. |
||
|
||
// extracting required parameters for RFC 2069 simpler Digest | ||
// String _realm = _exractParam(authReq, "realm=\"", '"'); | ||
String _realm = "Protected"; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can you explain why it says "extracting required parameters" and then the |
||
String _nonce = _exractParam(authReq, "nonce=\"", '"'); | ||
// String _nonce = "2cadff7e2f160969"; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. is this commented out line still needed? if not, please remove it. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You are right, I removed them all. |
||
String _opaque = _exractParam(authReq, "opaque=\"", '"'); | ||
|
||
// parameters for the RFC 2617 newer Digest | ||
MD5Builder md5; | ||
md5.begin(); | ||
md5.add(username + ":" + _realm + ":" + password); // md5 of the user:realm:user | ||
md5.calculate(); | ||
String _H1 = md5.toString(); | ||
|
||
md5.begin(); | ||
md5.add(String("GET:") + String("/api/state?power=0")); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It might be worth storing the URI part in a separate variable and using it both when making HTTP call and here, instead of duplicating. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes I created separate variables for them |
||
md5.calculate(); | ||
String _H2 = md5.toString(); | ||
|
||
md5.begin(); | ||
md5.add(_H1 + ":" + _nonce + ":" + "00000001" + ":" + "gDBuFY4s" + ":" + "auth" + ":" + _H2); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What are the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In digest authentication client must generate nonce count and client nonce we set them here manually but they can set by creating a random string. |
||
md5.calculate(); | ||
String _response = md5.toString(); | ||
|
||
http.begin("http://192.168.100.1/api/state?power=0"); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Likewise, use a variable for URI to avoid duplication. |
||
USE_SERIAL.println(_nonce); | ||
String Author = "Digest username=\"admin\", realm=\"Protected\", nonce=\"" + _nonce + "\", uri=\"/api/state?power=0\", algorithm=\"MD5\", qop=auth, nc=00000001, cnonce=\"gDBuFY4s\", response=\"" + _response + "\"\r\n"; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Suggest wrapping this part of the code (starting from extractParam calls) into a function which users can copy into their own sketch. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. username and URI are duplicated here again, along with nonces... |
||
USE_SERIAL.println(Author); | ||
http.addHeader("Authorization", Author); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please use lowercase names for local variables. Also, the name |
||
|
||
http.GET(); | ||
|
||
payload = http.getString(); | ||
USE_SERIAL.println(payload); | ||
} else { | ||
USE_SERIAL.printf("[HTTP] GET... failed, error: %s\n", http.errorToString(httpCode).c_str()); | ||
} | ||
|
||
http.end(); | ||
} | ||
|
||
delay(10000); | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Suggest using
Serial
directly