Carte shield ethernet et mot de passe

Bonjour, j'aimerais savoir comment mettre un mot de passe sur un serveur.

En gros je voudrais qu'une fentre s'ouvre avant la page html et que le bon mot de passe et utilisateur permettent l'accé a une page.

Est ce possible avec un ardunio uno et une carte ethernet?

Oui, c'est possible.
Mais il faut le gérer dans tes pages HTML avec un cookie par exemple ou un paramètre HTTP.
A moins qu'une librairie le gère pour toi.

Quel es ton code et la façon dont tu gère ton serveur HTTP sur ton Arduino ?

Bonjour, mon code est tout simple:

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

// Remplacez ces valeurs par les paramètres de votre réseau local
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
IPAddress ip(192, 168, 1, 177);
EthernetServer server(80);

void setup() {
  Ethernet.begin(mac, ip);
  server.begin();
}

void loop() {
  EthernetClient client = server.available();

  if (client) {
    Serial.println("New client connected");
    client.println("HTTP/1.1 200 OK");
    client.println("Content-Type: text/html");
    client.println();

    client.println("<!DOCTYPE HTML>");
    client.println("<html>");
    client.println("<head><title>Hello World</title></head>");
    client.println("<body>");
    client.println("<h1>Hello, World!</h1>");
    client.println("</body>");
    client.println("</html>");

    delay(10);
    client.stop();
    Serial.println("Client disconnected");
  }
}

Salut.
Tu imagineras facilement qu'ajouter un accès sécurisé à un WebServer aussi simpliste n'est pas très utile.
Soit il s'agit d'un petit exercice personnel, soit le serveur doit évoluer vers quelque chose de plus conséquent. Dans le deuxième cas une UNO ne permettra pas d'aller bien loin.
Si tu en disais un peu plus ?

Bonjour, mon but c est de commander des relays depuis l interface html, depuis internet donc il me faut une authentification par mot de passe.

OK, donc le logiciel devrait tenir dans une UNO.
Par contre cela implique d'avoir certaines connaissances :

  • savoir recevoir une URL
  • savoir l'analyser pour afficher la page adéquate

Ce serait certainement plus facile avec un ESP32. Mais des solutions existent. Plutôt que d'utiliser la librairie Ethernet brute de fonderie :

Un exemple avec login :

Ça paraît un peu usine a gaz pour faire juste une authentification !

La complexité ne se gère pas de manière simple. Tu t'en rendras vite compte si tu essaies de faire la même chose sans librairie spécialisée, avec seulement la librairie Ethernet

Ok, je vais essayer cette librairie.

Esr t elle bien compatible arduino uno?

J'ai reussi a trouver : defines.h

J'ai un problème de compilation:

Ethernet_Generic.h pas trouvé

J'ai un doute @hbachetti pourrait confirmer

Et as-tu cherché Ethernet_Generic.h sur Google ?
Une deuxième librairie à installer, probablement.

Après examen de l'exemple, celui-ci utilise beaucoup trop d'objets String, ce qui pourrait conduire à de la fragmentation mémoire.
Mais il existe d'autres librairies : cherche
arduino ethernet webserver library
sur google.

Essaye celle-ci par exemple :
https://codebender.cc/library/WebServer

Cet exemple :
https://codebender.cc/example/WebServer/Web_Authentication#Web_Authentication.ino

Sinon, d'autres exemples utilisent la librairie Ethernet seule. Je te propose de jeter un oeil à ce code pour comprendre comment faire :

Mais il te restera la partie login à coder toi-même.

J'ai trouvé ce site avec un exemple de commandes de plusieurs pin par un formulaire et la methode get.

Dans mon code ci-dessous j'ai crée un formulaire rudimentaire, j'arrive a récuperer la requete de type GET, j'ai ceci:

GET /?user_name=user&pass=pass HTTP/1.1

Ma question est comment recuperer facilement le nom d'utilisateur et le mot de passe, en gros comment parser l'url?

Mon code:

/*
 Created by Rui Santos
 Visit: https://randomnerdtutorials.com for more arduino projects

 Arduino with Ethernet Shield
 */

#include <SPI.h>
#include <Ethernet.h>
#include <Servo.h> 
int led = 4;
Servo microservo; 
int pos = 0; 
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };   //physical mac address
byte ip[] = { 192, 168, 0, 178 };                      // ip in lan (that's what you need to use in your browser. ("192.168.1.178")
byte gateway[] = { 192, 168, 0, 254 };                   // internet access via router
byte subnet[] = { 255, 255, 255, 0 };                  //subnet mask
EthernetServer server(80);                             //server port     
String readString;


void setup() {
 // Open serial communications and wait for port to open:
  Serial.begin(9600);
   while (!Serial) {
    ; // wait for serial port to connect. Needed for Leonardo only
  }
  pinMode(led, OUTPUT);
  microservo.attach(7);
  // start the Ethernet connection and the server:
  Ethernet.begin(mac, ip, gateway, subnet);
  server.begin();
  Serial.print("server is at ");
  Serial.println(Ethernet.localIP());
}







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); //print to serial monitor for debuging
           formulaire(client);
           delay(1);
           //stopping client
           client.stop();
           

           // ici comment parser l'url
           /*if (readString.indexOf("?button1on") >0){
               digitalWrite(led, HIGH);
           }
           if (readString.indexOf("?button1off") >0){
               digitalWrite(led, LOW);
           }
            */


   
            //clearing string for next read
            readString="";  
           
         }
       }
    }
}
}









 void formulaire(EthernetClient& client){

           client.println("HTTP/1.1 200 OK");
           client.println("Content-Type: text/html");
           client.println("");     
           client.println("<HTML>");
           client.println("<HEAD>");
           client.println("<TITLE>Formulaire</TITLE>");
           client.println("</HEAD>");
           client.println("<BODY>");
           client.println("<H1>Autentification</H1>");
           client.println("<hr />");
           client.println("<br />");  
           client.println("<H2>Formulaire</H2>");
           client.println("<br />");  
           client.println("<form action=\"/\" method=\"GET\">");
           client.println("USER:"); 
           client.println("<input type=\"text\" id=\"user\" name=\"user_name\" />");   
           client.println("<br />"); 
           client.println("PASS:");     
           client.println("<input type=\"text\" id=\"pass\" name=\"pass\" />");
           client.println("<br />"); 
           client.println("<button type=\"submit\">Envoyer</button>");

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


}










void helloWorldPage(EthernetClient& client) {
  client.println("HTTP/1.1 200 OK");
  client.println("Content-Type: text/html");
  client.println();
  client.println("<html><body>");
  client.println("<h1>Hello World!</h1>");
  client.println("</body></html>");
}




Tu commences à entrevoir le côté dificile de l'utilisation de la librairie Ethernet seule.
Un parser peut être écrit avec strtok.
Mais une librairie du type WebServer ferait cela à ta place.

J'ai déja fais du parsing, mais pas pour arduino... Je cherche les bonnes fonctions

Je bute sur un problème:

J'ai reussi a supprimer le debut et la fin de ma chaine, j'obtiens une chaine comme ceci:

user_name=11111&pass=22222

J'ai essayé d'utiliser la fonction strtok(), hors il semble qu'elle marche que sur des CHAR, donc j'obtiens une erreur de compilation:

Compilation error: cannot convert 'String' to 'char*' for argument '1' to 'char* strtok(char*, const char*)'

Voici mon code qui pose problème (ma string s'appelle readString):

 char *token = strtok(readString, '&');


           while( token != NULL ) {
              Serial.println(token);
              token = strtok(NULL, '&');
            }

Sa ne marche donc pas sur des strings? Comment faire?

readString.c_str()

Mais le plus simple serait de construire une c_string au lieu d'une String dans ta boucle de lecture ou de parser à la volée en guettant le caractère =

Merci , j'essairais demain.

Par contre entre temps j'ai trouvé ca :slight_smile:

char charBuf[50];
readString.toCharArray(charBuf, 50);

c_str retourne un const char *

Le dernier exemple que j'ai donné :

Utilise une Cstring. Encore une fois, encombrer la mémoire avec des String peut devenir cata avec une Uno.