I am posting this in the hope that, after sponging so much info and learning from this great forum over the past few months, I may be able to contribute back something that could be of use to other users.
After completing a small home automation system with controls accessible over the internet, I was concerned about (accidental or deliberate) unwanted access to the web server interface page.
The following is a basic sketch to password protect the web server page.
Credits : A major credit goes to Zoomkat for his huge input with this project. Without his help and coding, I would never have got this completed. Thanks Zoomkat.
This code may not be perfect ( except for Zoomkat's contributed parts ), and it may not be the most efficient way, but it is how I want my system to work and coded with my basic understanding so that I could follow it's operation.
The code works as follows :
If the code can not find a valid session ID in the received http, it displays the login page which requires a password.
When the user logs in, the current millis() is set as the session ID.
The page of options that is displayed after login contains the session ID in all the hyperlinks.
Click on a hyperlink sends the session ID and the command / action number to the Arduino based server.
The server then validates the session ID and performs the command / action, or if the session ID is invalid, shows the login form again.
There is a variable in the code ( passExpireMil ) that sets the idle time to wait before deleting a session ID. If set to passExpireMil = 60000, then if any link on the served page is not clicked within 60 seconds, the session expires and you need to login again.
Each click on any link on the page restarts the passExpireMil timer.
#include <SPI.h>
#include <Ethernet.h>
//ethernet setup
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; //physical mac address
IPAddress ip(192,168,1,101); // change to ip in lan
IPAddress gateway(192,168,1,254); // change to internet access via router
IPAddress subnet(255,255,255,0); // change to subnet mask
IPAddress myserver(41,00,00,00); // not used in this code, but used if writing data to a server based file
EthernetServer server(82); // server port : remember to set port forwarding on the DSL router
EthernetClient client; // Define a client object
const int passCount = 20;
unsigned long passIDstart[passCount]; // array to record start time of user sessions
unsigned long passIDlast[passCount]; // array to record last time of user sessions
unsigned long passIDvalid = 0; // set default as passID : 0 = missing or invalid
unsigned long passExpireMil = 60000; // expiry time for automatic expiry of valid passID
String readString; // used to clear away incoming data that is not required
char myPass[] = "1234"; // Valid password (1234 for testing)
char DoAction[] = "DoAction"; // keyword for DoAction commands
char buffer[256]; // buffer for debugging
char xx1[20]; // temp char for the long converted to char
char JoinedChar[100]; // char to hold the joined strings
String LastAction;
/*----------------------------------------------------------------------------*/
/* incoming data : Get a single client char */
/*----------------------------------------------------------------------------*/
char gchr(void){
while (!client.available()); /* Await data from client */
return client.read(); /* Return input character */
} /* end: gchr() */
/*----------------------------------------------------------------------------*/
/* incoming data : Get an entire line from the client */
/*----------------------------------------------------------------------------*/
char *glin(char *buf){
char c,*p = buf; /* Input char, input buffer pointer */
while (' ' > (c = gchr())); /* Discard (leading) control chars */
do *p++ = c; /* Move input char to line buffer */
while (' ' <= (c = gchr())); /* Until control char encountered */
*p = '\0'; /* Terminate line in buffer */
return buf; /* Return pointer to input string */
} /* end: glin() */
/*----------------------------------------------------------------------------*/
/* Arduino standard setup() function */
/*----------------------------------------------------------------------------*/
void setup(void){
pinMode(4,OUTPUT); /* pin selected to control */
Ethernet.begin(mac,ip,subnet,gateway); /* Initialize ethernet device */
server.begin(); /* Listen for connections */
Serial.begin(9600); /* Connect to serial monitor */
//initialize the passIDstart array to hold zero values in all elements
for (int i=0; i < passCount; i++){
passIDstart[i] = 0;
}
Serial.println("Setup Done");
} /* end: setup() */
/*----------------------------------------------------------------------------*/
/* Arduino standard loop() function */
/*----------------------------------------------------------------------------*/
void loop(void) {
unsigned long currentMillis = millis();
if (client = server.available()) { // Request client connection
while (client.connected()) { // Is there client data available?
glin(buffer); // Get HTTP request line by line
Serial.print("The current millis is : ");
Serial.println(millis());
Serial.print("Received: '"); // Show what we received from
Serial.print(buffer); // the current client
Serial.println("'");
passIDvalid = 0; // set the passIDvalid to 0
LastAction = "";