How to make a login form using HTML that connects to the next page

Hello, could you please take a look at my code that i got it from Ethernet_Pan_Tilt_Arduino/Pan_Tilt_Webpage_Ethernet.pde at master · sklemp/Ethernet_Pan_Tilt_Arduino · GitHub and make some modification on it. So, basically, i just want to add the login form page at the first page for the security things and then go to the second page to control servo motor. At first, i thought about using webserver library, but it looked harder to understand, so i prefer to use HTML, but i’m still newbie on that. Could you help me, give some example about making a login form page and then go to the second page to contol something ? Thank you for your time and looking forward to a reply.

My code :

#include <SPI.h>
#include <Client.h>
#include <Ethernet.h>
#include <Servo.h>

Servo tilt;
Servo pan;

int time = 570;
int tiltpos = 0;
int tilt_cnt = 15; 
int tilt_steps = 0;

byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };   //physical mac address
byte ip[] = { 192, 168, 0, 177 };                      // ip in lan (that's what you need to use in your browser. ("192.168.1.177")
byte gateway[] = { 192, 168, 0, 1 };                   // internet access via router
byte subnet[] = { 255, 255, 255, 0 };                  //subnet mask
EthernetServer server(80);                             //server port     
String readString = String(30);

void setup(){
  Ethernet.begin(mac, ip, gateway, subnet);
  Serial.begin(9600);
  tilt.attach(6); 
  tilt.write(90);
  pan.writeMicroseconds(1500);
}

void loop(){

  
  
  EthernetClient client = server.available();
  if(client){
    while(client.connected()){
      if(client.available()){
        char c = client.read();
        if(readString.length()<100)
        {readString += c;
        }
        Serial.print(c);
      if(c == '\n'){
        if(readString.indexOf("?")<0)
        {
        }
        else
        {
          if(readString.indexOf("UP=UP")>0)
          {tilt_up();
          }
          else if(readString.indexOf("DN=DN")>0)
          {tilt_down();
          }
        }
        
       client.println("HTTP/1.1 200 OK"); //send new page
           client.println("Content-Type: text/html");
           client.println();
           client.print("<body style=background-color:green>");
           client.println("<center>");
           client.println("<hl>Control ServoMotor</hl>");
           client.println("<hr />");
           client.println("Servo Horizontal :");
           client.println(tilt_steps);
           client.println("<form method=get name=SERVO>");
           client.println("<input type=submit value=UP name=UP style=\"width:100px\">
");
           client.println("<input type=submit value=DN name=DN style=\"width:100px\">");
           client.println("</form>");
           client.println("</center>");
           client.println("</body></html>");  
           readString="";
           client.stop();
      }
      }
    }
  }
}


void tilt_up(){
  tiltpos = tilt.read();
  if(tiltpos>=0 && tiltpos <180)
  {
    tilt.write(tiltpos+tilt_cnt);
    tilt_steps=tilt_steps+15;
  }
}
void tilt_down(){
  tiltpos = tilt.read();
  if(tiltpos>0)
  {
    tilt_steps=tilt_steps-15;
    tilt.write(tiltpos-tilt_cnt);
  }
}

I also have an example for making a login form with HTML, but i don’t know how to implement it on the sketch above.
Here’s the HTML code for simple login form :

<html>
<head>
<title>
Login page
</title>
</head>
<body>
<h1 style="font-family:Comic Sans Ms;text-align="center";font-size:20pt;
color:#00FF00;>
Simple Login Page
</h1>
<form name="login">
Username<input type="text" name="userid"/>
Password<input type="password" name="pswrd"/>
<input type="button" onclick="check(this.form)" value="Login"/> /*this one also, "check(this.form)", i don't know how to write it using ethernet shield */
<input type="reset" value="Cancel"/>
</form>
<script language="javascript">
function check(form)/*function to check userid & password*/ /*this one, i don't know how to write it using ethernet shield*/
{
 /*the following code checkes whether the entered userid and password are matching*/
 if(form.userid.value == "test" && form.pswrd.value == "test")
  {
    /*new page for controling motor*/
  }
 else
 {
   alert("Error Password or Username")/*displays error message*/
  }
}
</script>
</body>
</html>

Thank you

So, it doesn't matter what the client requested? You are always going to return the same page. I don't think that is going to work well.

Thank you for your reply PaulS. So, it means that my example of login form won't work properly ? I'm really sorry, because i'm really lack of knowledge about HTML things. I've read about the question before in this link http://forum.arduino.cc/index.php/topic,193446.0.html , and does it work if i use the way Zoomkat told us the example to make 2 pages ?. Could you please give me any link or some info how to make a 2 pages using ethernet shield without using webserver library ? B/c i haven't found it yet T__T ! Or maybe should i use SD card to read file with extension HTML inside then go to another page ( but i don't know if it's going to work because the size of buffer memory in arduino uno ). Thank you

I just want to make a login form page, and then go to the next page which client request is important.

I just want to make a login form page, and then go to the next page which client request is important.

You might do something simple like below. Make two web pages, one login and one control. Make a simple login page for the password, with a secret click link to the control page if the password is detected. The below is just a quick to some code with the submit box. Load the page in a browser and send mypassword in the submit box. The same page should reload with the secret click link.

//zoomkat 12-08-12
//get submit box code
//for use with IDE 1.0
//open serial monitor to see what the arduino receives
//use the \ slash to escape the " in the html or use a '
//address will look like http://192.168.1.102:84 when submited
//for use with W5100 based ethernet shields
//note that the below bug fix may be required
// http://code.google.com/p/arduino/issues/detail?id=605 

#include <SPI.h>
#include <Ethernet.h>

byte mac[] = { 
  0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; //physical mac address
byte ip[] = { 
  192, 168, 1, 102 }; // ip in lan
byte gateway[] = { 
  192, 168, 1, 1 }; // internet access via router
byte subnet[] = { 
  255, 255, 255, 0 }; //subnet mask
EthernetServer server(84);
; //server port

String readString; 

//////////////////////

void setup(){

  pinMode(5, OUTPUT); //pin selected to control
  //start Ethernet
  Ethernet.begin(mac, ip, gateway, gateway, subnet);
  server.begin();

  //enable serial data print 
  Serial.begin(9600); 
  Serial.println("server text box test1"); // so I can keep track of what is loaded
}

void loop(){
  // Create a client connection
  EthernetClient client = server.available();
  if (client) {
    while (client.connected()) {
      if (client.available()) {
        char c = client.read();

        //read char by char HTTP request
        if (readString.length() < 100) {

          //store characters to string 
          readString += c; 
          //Serial.print(c);
        } 

        //if HTTP request has ended
        if (c == '\n') {

          ///////////////
          Serial.println(readString); //see what was captured

          //now output HTML data header

          client.println("HTTP/1.1 200 OK");
          client.println("Content-Type: text/html");
          client.println();

          client.println("<HTML>");
          client.println("<HEAD>");
          client.println("<TITLE>Arduino GET test page</TITLE>");
          client.println("</HEAD>");
          client.println("<BODY>");

          client.println("<H1>HTML form GET example</H1>");

          client.println("<FORM ACTION='/' method=get >"); //uses IP/port of web page

          client.println("Pin 5 'on5' or 'off5': <INPUT TYPE=TEXT NAME='LED' VALUE='' SIZE='25' MAXLENGTH='50'>
");

          client.println("<INPUT TYPE=SUBMIT NAME='submit' VALUE='Change Pin 5!'>");

          client.println("</FORM>");

          client.println("
");

          //check for mypassword
          if(readString.indexOf("mypassword") >0) {
            //link to a second control page
            client.println("<a href='/ctrl' '>secret click link</a>");
          }

          client.println("</BODY>");
          client.println("</HTML>");

          delay(1);
          //stopping client
          client.stop();

          /////////////////////
          if(readString.indexOf("on5") >0)//checks for on
          {
            digitalWrite(5, HIGH);    // set pin 5 high
            Serial.println("Led On");
          }
          if(readString.indexOf("off5") >0)//checks for off
          {
            digitalWrite(5, LOW);    // set pin 5 low
            Serial.println("Led Off");
          }
          //clearing string for next read
          readString="";

        }
      }
    }
  }
}

It would certainly be helpful if you understood client/server communication, and what providing a login page means, before you try to implement something.

If you point your browser at http://my.wonderful.site.com, and see a login page, then what the client (the browser) has done is connect to the server (my.wonderful.site.com), and issued a GET request ("GET / HTTP1.1"). The server returns a stream of data containing html tags that include a form tag, some text editor input fields (for user name and password), and a submit button (and probably some other stuff like a register button, a "Forgot my password link", a "Forgot my user name" link, etc.).

The form has an action associated with it. That action generates another GET request, with data from the input fields - something like "GET /?username=PaulS&password=nosyBastard". It is likely that the client will have been told to encrypt the password, rather than sending it as plain text.

The server, then, sees a DIFFERENT request for a page, and has additional information. The server uses that additional information to determine that the user is known, or not, and does a redirect to a different page. It may send a cookie to the client containing a token that all future GET requests should contain, so that the user name and password don't have to be sent (and checked) again with each request.

You will never get anywhere with having the Arduino serve up a page containing a login screen, and then serve up different pages to authorized users and non-authorized users, until you pay attention to what the client asked for in the GET request.

To make things a little more secure, use POST or ajax when transmitting user/pass so it doesn't show up in the url browser field.

If the user/pass is correct, you set an internal arduino variable to true or to the name of the user aka a session variable. All 'html' pages look at this so it will display or deny display depending. When the user logs out or set a timer to set the session variable to false.

ps. keep the user/pass in the arduino code.

First of all, i would like to thank to all of you guys : zoomkat, PaulS, and mistergreen for the help. Those thing really make me learn how to understand the way user/pass work in arduino. And also for PaulS, big thanks to you master for your explanation that makes me easier to understand about HTML request works especially using GET method. Just for your information, i read it about 5 times to understand, ahahaha… ( i’m not a smart person who’s quick learner ).
And for master Zoomkat, thanks for the example of your script and i learn many new things from you, such as use the \ slash to escape the " in the html or use a ’

I’ll try it later, and don’t feel bored to answer my next stupid question.
Thanks for the help to all of you >,<v !

If the user/pass is correct, you set an internal arduino variable to true or to the name of the user aka a session variable.

The user/pass may be correct for that client for that session. But, the connection with that client ends as soon as the server generates a response. If the client doesn't provide the "I'm an authorized user" token next time, how is the Arduino to know that it is the same client? The Arduino does not have any way of knowing that the same client is making another request, unless the client knows the magic phrase (which is something stored in a cookie, generally). And, the Arduino doesn't send cookies.

PaulS:

If the user/pass is correct, you set an internal arduino variable to true or to the name of the user aka a session variable.

The user/pass may be correct for that client for that session. But, the connection with that client ends as soon as the server generates a response. If the client doesn't provide the "I'm an authorized user" token next time, how is the Arduino to know that it is the same client? The Arduino does not have any way of knowing that the same client is making another request, unless the client knows the magic phrase (which is something stored in a cookie, generally). And, the Arduino doesn't send cookies.

My setup is a one user interaction although not very secure. If somebody tries to see your site while you're logged on, they can.

If you want multiple users and something more secure: sessions work by creating a unique id (UID) for each visitor and store variables based on this UID. The UID is either stored in a cookie or is propagated in the URL. You'd store the session in an array rather than a variable on the arduino. The arduino can send the UID to the client and the client can create the client side cookie with Javascript. That way they can sync up.

I was working on my own login and found a solution. The arduino can write a cookie to the browser to create a session id.

On logged in, write in the header

        arduinoSession = millis();
        client.println("HTTP/1.1 200 OK");
        client.println("Content-Type: text/html");
        client.print("Set-cookie: ARDUINOSESSIONID=");
        client.print(arduinoSession);
        client.println("; HttpOnly");
        client.println("Connection: keep-alive");
        client.println();

I'm using millis() to create a cheap unique id. A little video explaining it http://www.youtube.com/watch?v=3UcKvr8Idpo

Interesting post!

zoomkat: Interesting post!

Thanks.

I want to clarify what wasn't in the video. The cookie's life span you create is a temporary one, as long as the window is open. You can specify an expiration date. Also the Browser automatically sends the cookie info back to the sever every time you make a call (as long it's the same domain of course).

Oh, and this is a one user session only. If you want multiple users, you'd have to create a session array on your server and cycle through it to see who is who.

Thanks sir for your information and ! It really helped me a lot ! Once again, thank you !

I suggest that your clients should not explicitly request the login page. They should request whatever page they eventually want access to. Regardless of what page the client requests, the server should check whether the client is logged in and if not, return the login page. The destination URL for the login page should be the same as the client's original request i.e. if you request the URL outside of a logged-in session you get the login page, and if you request it within a logged-in session (and assuming the logged-in user has rights to access the requested resource) you get the page you asked for.