Authentification HTTP du serveur Web ESP32/ESP8266 (protégé par nom d’utilisateur et mot de passe)

Authentification HTTP du serveur Web ESP32/ESP8266 (protégé par nom d'utilisateur et mot de passe)

Découvrez comment ajouter une authentification HTTP avec nom d’utilisateur et mot de passe à vos projets de serveur Web ESP32 et ESP8266 NodeMCU à l’aide de l’IDE Arduino. Vous ne pouvez accéder à votre serveur Web que si vous saisissez l’utilisateur et le mot de passe corrects. Si vous vous déconnectez, vous ne pouvez accéder à nouveau que si vous entrez les bonnes informations d’identification.

La méthode que nous allons utiliser peut être appliquée aux serveurs Web construits à l’aide de la bibliothèque ESPAsyncWebServer.

ESP32 ESP8266 Serveur Web NodeMCU Authentification HTTP Nom d'utilisateur et mot de passe protégé Arduino IDE

Les cartes ESP32/ESP8266 seront programmées à l’aide de l’IDE Arduino. Assurez-vous donc que ces cartes sont installées :

Problèmes de sécurité

Ce projet est destiné à être utilisé dans votre réseau local pour vous protéger de toute personne tapant simplement l’adresse IP ESP et accédant au serveur Web (comme un membre de la famille ou un ami non autorisé).

Si votre réseau est correctement sécurisé, l’exécution d’un serveur HTTP avec une authentification de base suffit pour la plupart des applications. Si quelqu’un a réussi à pirater votre réseau, peu importe que vous utilisiez HTTP ou HTTPS. Le pirate peut contourner HTTPS et obtenir votre utilisateur/passe.

Aperçu du projet

Jetons un coup d’œil aux fonctionnalités du projet que nous allons construire.

Présentation du projet de serveur Web protégé par mot de passe ESP32 ESP8266 NodeMCU
  • Dans ce didacticiel, vous apprendrez à protéger votre serveur Web par mot de passe.
  • Lorsque vous essayez d’accéder à la page du serveur Web sur l’adresse IP ESP, une fenêtre apparaît demandant un nom d’utilisateur et un mot de passe ;
  • Pour accéder à la page du serveur Web, vous devez entrer le bon nom d’utilisateur et le bon mot de passe (définis dans le sketch ESP32/ESP8266) ;
  • Il y a un bouton de déconnexion sur le serveur Web. Si vous cliquez sur le bouton de déconnexion, vous serez redirigé vers une page de déconnexion. Ensuite, fermez tous les onglets du navigateur Web pour terminer le processus de déconnexion ;
  • Vous ne pouvez accéder à nouveau au serveur Web que si vous vous connectez avec les bonnes informations d’identification ;
  • Si vous essayez d’accéder au serveur Web à partir d’un autre appareil (sur le réseau local), vous devez également vous connecter avec les bonnes informations d’identification (même si vous avez réussi à vous connecter sur un autre appareil) ;
  • L’authentification n’est pas cryptée.

Noter: ce projet a été testé sur les navigateurs Web Google Chrome et Firefox et sur les appareils Android.

Installation de bibliothèques – Serveur Web asynchrone

Pour construire le serveur Web, vous devez installer les bibliothèques suivantes :

Ces bibliothèques ne peuvent pas être installées via le gestionnaire de bibliothèque Arduino, vous devez donc copier les fichiers de bibliothèque dans le dossier Bibliothèques d’installation Arduino. Alternativement, dans votre IDE Arduino, vous pouvez accéder à Esquisser > Inclure la bibliothèque > Ajouter une bibliothèque .zip et sélectionnez les bibliothèques que vous venez de télécharger.

Code de serveur Web avec authentification

Copiez le code suivant dans votre IDE Arduino.

/*********
  Rui Santos
  Complete project details at https://Raspberryme.com/esp32-esp8266-web-server-http-authentication/
  
  The above copyright notice and this permission notice shall be included in all
  copies or substantial portions of the Software.
*********/

// Import required libraries
#ifdef ESP32
  #include <WiFi.h>
  #include <AsyncTCP.h>
#else
  #include <ESP8266WiFi.h>
  #include <ESPAsyncTCP.h>
#endif
#include <ESPAsyncWebServer.h>

// Replace with your network credentials
const char* ssid = "REPLACE_WITH_YOUR_SSID";
const char* password = "REPLACE_WITH_YOUR_PASSWORD";

const char* http_username = "admin";
const char* http_password = "admin";

const char* PARAM_INPUT_1 = "state";

const int output = 2;

// Create AsyncWebServer object on port 80
AsyncWebServer server(80);

const char index_html[] PROGMEM = R"rawliteral(
<!DOCTYPE HTML><html>
<head>
  <title>ESP Web Server</title>
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <style>
    html {font-family: Arial; display: inline-block; text-align: center;}
    h2 {font-size: 2.6rem;}
    body {max-width: 600px; margin:0px auto; padding-bottom: 10px;}
    .switch {position: relative; display: inline-block; width: 120px; height: 68px} 
    .switch input {display: none}
    .slider {position: absolute; top: 0; left: 0; right: 0; bottom: 0; background-color: #ccc; border-radius: 34px}
    .slider:before {position: absolute; content: ""; height: 52px; width: 52px; left: 8px; bottom: 8px; background-color: #fff; -webkit-transition: .4s; transition: .4s; border-radius: 68px}
    input:checked+.slider {background-color: #2196F3}
    input:checked+.slider:before {-webkit-transform: translateX(52px); -ms-transform: translateX(52px); transform: translateX(52px)}
  </style>
</head>
<body>
  <h2>ESP Web Server</h2>
  <button onclick="logoutButton()">Logout</button>
  <p>Ouput - GPIO 2 - State <span id="state">%STATE%</span></p>
  %BUTTONPLACEHOLDER%
<script>function toggleCheckbox(element) {
  var xhr = new XMLHttpRequest();
  if(element.checked){ 
    xhr.open("GET", "/update?state=1", true); 
    document.getElementById("state").innerHTML = "ON";  
  }
  else { 
    xhr.open("GET", "/update?state=0", true); 
    document.getElementById("state").innerHTML = "OFF";      
  }
  xhr.send();
}
function logoutButton() {
  var xhr = new XMLHttpRequest();
  xhr.open("GET", "/logout", true);
  xhr.send();
  setTimeout(function(){ window.open("/logged-out","_self"); }, 1000);
}
</script>
</body>
</html>
)rawliteral";

const char logout_html[] PROGMEM = R"rawliteral(
<!DOCTYPE HTML><html>
<head>
  <meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
  <p>Logged out or <a href="https://www.raspberryme.com/">return to homepage</a>.</p>
  <p><strong>Note:</strong> close all web browser tabs to complete the logout process.</p>
</body>
</html>
)rawliteral";

// Replaces placeholder with button section in your web page
String processor(const String& var){
  //Serial.println(var);
  if(var == "BUTTONPLACEHOLDER"){
    String buttons ="";
    String outputStateValue = outputState();
    buttons+= "<p><label class=\"switch\"><input type=\"checkbox\" onchange=\"toggleCheckbox(this)\" id=\"output\" " + outputStateValue + "><span class=\"slider\"></span></label></p>";
    return buttons;
  }
  if (var == "STATE"){
    if(digitalRead(output)){
      return "ON";
    }
    else {
      return "OFF";
    }
  }
  return String();
}

String outputState(){
  if(digitalRead(output)){
    return "checked";
  }
  else {
    return "";
  }
  return "";
}

void setup(){
  // Serial port for debugging purposes
  Serial.begin(115200);

  pinMode(output, OUTPUT);
  digitalWrite(output, LOW);
  
  // Connect to Wi-Fi
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(1000);
    Serial.println("Connecting to WiFi..");
  }

  // Print ESP Local IP Address
  Serial.println(WiFi.localIP());

  // Route for root / web page
  server.on("https://www.raspberryme.com/", HTTP_GET, [](AsyncWebServerRequest *request){
    if(!request->authenticate(http_username, http_password))
      return request->requestAuthentication();
    request->send_P(200, "text/html", index_html, processor);
  });
    
  server.on("/logout", HTTP_GET, [](AsyncWebServerRequest *request){
    request->send(401);
  });

  server.on("/logged-out", HTTP_GET, [](AsyncWebServerRequest *request){
    request->send_P(200, "text/html", logout_html, processor);
  });

  // Send a GET request to <ESP_IP>/update?state=<inputMessage>
  server.on("/update", HTTP_GET, [] (AsyncWebServerRequest *request) {
    if(!request->authenticate(http_username, http_password))
      return request->requestAuthentication();
    String inputMessage;
    String inputParam;
    // GET input1 value on <ESP_IP>/update?state=<inputMessage>
    if (request->hasParam(PARAM_INPUT_1)) {
      inputMessage = request->getParam(PARAM_INPUT_1)->value();
      inputParam = PARAM_INPUT_1;
      digitalWrite(output, inputMessage.toInt());
    }
    else {
      inputMessage = "No message sent";
      inputParam = "none";
    }
    Serial.println(inputMessage);
    request->send(200, "text/plain", "OK");
  });
  
  // Start server
  server.begin();
}
  
void loop() {
  
}

Afficher le code brut

Il vous suffit d’entrer vos informations d’identification réseau (SSID et mot de passe) et le serveur Web fonctionnera immédiatement. Le code est compatible avec les deux ESP32 et ESP8266 planches.

Par exemple, nous construisons un serveur Web qui contrôle GPIO 2. Vous pouvez utiliser l’authentification HTTP avec n’importe quel serveur Web construit avec le Bibliothèque ESPAsyncWebServer.

Comment fonctionne le code

Nous avons déjà expliqué en détail le fonctionnement des serveurs Web comme celui-ci dans les didacticiels précédents (serveur Web de température DHT ou serveur Web relais), nous allons donc simplement jeter un œil aux parties pertinentes pour ajouter l’authentification par nom d’utilisateur et mot de passe au serveur Web. .

Informations d’identification réseau

Comme mentionné précédemment, vous devez insérer vos informations d’identification réseau dans les lignes suivantes :

const char* ssid = "REPLACE_WITH_YOUR_SSID";
const char* password = "REPLACE_WITH_YOUR_PASSWORD";

Définition de votre nom d’utilisateur et de votre mot de passe

Dans les variables suivantes, définissez le nom d’utilisateur et le mot de passe de votre serveur Web. Par défaut, le nom d’utilisateur est administrateur et le mot de passe est aussi administrateur. Nous recommandons vivement de les changer.

const char* http_username = "admin";
const char* http_password = "admin";

Bouton de déconnexion

Dans le index_html variable, vous devez ajouter du texte HTML pour ajouter un bouton de déconnexion. Dans cet exemple, il s’agit d’un simple bouton de déconnexion sans style pour simplifier les choses.

<button onclick="logoutButton()">Logout</button>

Lorsqu’il est cliqué, le bouton appelle le bouton de déconnexion() Fonction JavaScript. Cette fonction envoie une requête HTTP GET à votre ESP32/ESP8266 sur le /Se déconnecter URL. Ensuite, dans le code ESP, vous devez gérer ce qui se passe après avoir reçu cette demande.

function logoutButton() {
  var xhr = new XMLHttpRequest();
  xhr.open("GET", "logout", true);
  xhr.send();

Une seconde après avoir cliqué sur le bouton de déconnexion, vous êtes redirigé vers la page de déconnexion sur le /déconnecté URL.

  setTimeout(function(){ window.open("/logged-out","_self"); }, 1000);
}

Gérer les demandes avec authentification

Chaque fois que vous faites une demande à l’ESP32 ou à l’ESP8266 pour accéder au serveur Web, il vérifie si vous avez déjà entré le nom d’utilisateur et le mot de passe corrects pour vous authentifier.

En gros, pour ajouter une authentification à votre serveur web, il vous suffit d’ajouter les lignes suivantes après chaque requête :

if(!request->authenticate(http_username, http_password))
    return request->requestAuthentication();

Ces lignes ouvrent continuellement la fenêtre d’authentification jusqu’à ce que vous insériez les bonnes informations d’identification.

Vous devez le faire pour toutes les demandes. De cette façon, vous vous assurez que vous n’obtiendrez des réponses que si vous êtes connecté.

Par exemple, lorsque vous essayez d’accéder à l’URL root (adresse IP ESP), vous ajoutez les deux lignes précédentes avant d’envoyer la page. Si vous entrez les mauvaises informations d’identification, le navigateur continuera à les demander.

server.on("https://www.raspberryme.com/", HTTP_GET, [](AsyncWebServerRequest *request){
  if(!request->authenticate(http_username, http_password))
    return request->requestAuthentication();
  request->send_P(200, "text/html", index_html, processor);
});

Voici un autre exemple lorsque l’ESP reçoit une demande sur le /Etat URL.

server.on("/state", HTTP_GET, [] (AsyncWebServerRequest *request) {
  if(!request->authenticate(http_username, http_password))
    return request->requestAuthentication();
  request->send(200, "text/plain", String(digitalRead(output)).c_str());
});

Gérer le bouton de déconnexion

Lorsque vous cliquez sur le bouton de déconnexion, l’ESP reçoit une demande sur le /Se déconnecter URL. Lorsque cela se produit, envoyez le code de réponse 401.

server.on("/logout", HTTP_GET, [](AsyncWebServerRequest *request){
  request->send(401);
});

Le code de réponse 401 est un code d’état de réponse HTTP d’erreur non autorisée indiquant que la demande envoyée par le client n’a pas pu être authentifiée. Ainsi, cela aura le même effet qu’une déconnexion – il vous demandera le nom d’utilisateur et le mot de passe et ne vous permettra pas d’accéder à nouveau au serveur Web jusqu’à ce que vous vous connectiez.

Lorsque vous cliquez sur le bouton de déconnexion du serveur Web, après une seconde, l’ESP reçoit une autre requête sur le /déconnecté URL. Lorsque cela se produit, envoyez le texte HTML pour créer la page de déconnexion (déconnexion_html variable).

server.on("/logged-out", HTTP_GET, [](AsyncWebServerRequest *request){
  request->send_P(200, "text/html", logout_html, processor);
});

Manifestation

Téléchargez le code sur votre carte ESP32 ou ESP8266. Ensuite, ouvrez le moniteur série et appuyez sur le bouton RST/EN intégré pour obtenir son adresse IP.

Ouvrez un navigateur sur votre réseau local et saisissez l’adresse IP ESP.

La page suivante devrait se charger en demandant le nom d’utilisateur et le mot de passe. Entrez le nom d’utilisateur et le mot de passe et vous devriez avoir accès au serveur Web. Si vous n’avez pas modifié le code, le nom d’utilisateur est administrateur et le mot de passe est administrateur.

ESP32 ESP8266 NodeMCU Web Server Type d'authentification HTTP Nom d'utilisateur et mot de passe

Après avoir tapé le bon nom d’utilisateur et le bon mot de passe, vous devriez avoir accès au serveur Web.

ESP32 ESP8266 Serveur Web NodeMCU HTTP Auth Nom d'utilisateur et mot de passe protégés

Vous pouvez jouer avec le serveur Web et voir qu’il contrôle réellement la LED embarquée ESP32 ou ESP8266.

Carte ESP32 LED intégrée allumée HIGH

Dans la page du serveur Web, il y a un bouton de déconnexion. Si vous cliquez sur ce bouton, vous serez redirigé vers une page de déconnexion comme indiqué ci-dessous.

1643966646 548 Authentification HTTP du serveur Web ESP32ESP8266 protege par nom dutilisateur

Si vous cliquez sur le lien « retour à la page d’accueil », vous serez redirigé vers la page principale du serveur Web.

Si vous utilisez Google Chrome, vous devrez saisir le nom d’utilisateur et le mot de passe pour accéder à nouveau au serveur Web.

Si vous utilisez Firefox, vous devez fermer tous les onglets du navigateur Web pour vous déconnecter complètement. Sinon, si vous revenez à la page principale du serveur Web, vous y aurez toujours accès.

Nous vous conseillons donc de fermer tous les onglets du navigateur Web après avoir cliqué sur le bouton de déconnexion.

Vous devez également entrer le nom d’utilisateur et le mot de passe si vous essayez d’accéder à l’aide d’un autre appareil sur le réseau local, même si vous avez accès sur un autre appareil.

ESP32 ESP8266 Serveur Web NodeMCU Authentification HTTP Nom d'utilisateur et mot de passe Protégé Démonstration IDE Arduino

Conclusion

Dans ce didacticiel, vous avez appris à ajouter une authentification à vos serveurs Web ESP32 et ESP8266 (serveur Web protégé par mot de passe). Vous pouvez appliquer ce que vous avez appris dans ce didacticiel à n’importe quel serveur Web construit avec la bibliothèque ESPAsyncWebServer.

Nous espérons que vous avez trouvé ce tutoriel utile. Autres projets de serveur Web que vous pourriez aimer :

Apprenez-en plus sur les cartes ESP32 et ESP8266 avec nos ressources :

Merci d’avoir lu.