Web Server Password — Tutorial#

Arduino - Web Server Password —— Arduino Tutorial

HTTP 访问授权的过程

  1. When you initially type in the IP address of the Arduino into a web browser, the browser sends a request to the Arduino via HTTP, but without any username/password details.

  2. Upon receiving this request, the Arduino's code checks if there are any username/password credentials included. If none are found, the Arduino doesn't respond with the page's content. Instead, it sends back an HTTP message with headers instructing the browser to ask the user for their username/password. Importantly, this response doesn't contain HTML code for the login form.

  3. When the browser gets this response, it interprets the HTTP headers and understands that the Arduino is asking for a username/password. Consequently, the browser dynamically creates a login form for the user to input their credentials.

  4. The user then enters their username/password into this form.

  5. The browser includes the entered username/password in an HTTP request and sends it back to the Arduino.

  6. The Arduino checks the username/password included in the HTTP request. If they are correct, it provides the content of the requested page. If they are incorrect, the process is repeated, prompting the user to input the correct credentials again.

  7. Once the user correctly inputs their username/password for the first time, subsequent requests do not require them to re-enter the details. This is because the browser automatically saves the credentials and includes them in subsequent requests.

/*
 * Created by ArduinoGetStarted.com
 *
 * This example code is in the public domain
 *
 * Tutorial page: https://arduinogetstarted.com/tutorials/arduino-web-server-password
 */

#include <WiFiS3.h>

const char ssid[] = "YOUR_WIFI_SSID";  // change your network SSID (name)
const char pass[] = "YOUR_WIFI_PASSWORD";   // change your network password (use for WPA, or use as key for WEP)

int status = WL_IDLE_STATUS;

WiFiServer server(80);


const char* www_username = "admin";
const char* www_password = "arduino";

void setup() {
  Serial.begin(9600);
  delay(1000);
  String fv = WiFi.firmwareVersion();
  if (fv < WIFI_FIRMWARE_LATEST_VERSION)
    Serial.println("Please upgrade the firmware");

  // attempt to connect to WiFi network:
  while (status != WL_CONNECTED) {
    Serial.print("Attempting to connect to SSID: ");
    Serial.println(ssid);
    // Connect to WPA/WPA2 network. Change this line if using open or WEP network:
    status = WiFi.begin(ssid, pass);

    // wait 5 seconds for connection:
    delay(5000);
  }
  server.begin();
  Serial.print("IP Address: ");
  Serial.println(WiFi.localIP());
}

void loop() {
  // Check if a client has connected
  WiFiClient client = server.available();
  if (client) {
    Serial.println("Client connected");
    boolean authorized = checkAuthorization(client);

    if (authorized) {
      Serial.println("Client is authorized");
      client.println("HTTP/1.1 200 OK");
      client.println("Content-Type: text/html");
      client.println("Connection: close");
      client.println();
    
    // replaced by your HTML code here:
      client.println("<!DOCTYPE HTML>");
      client.println("<html>");
      client.println("<head><title>Arduino Web Server</title></head>");
      client.println("<body>");
      client.println("<h1>Login Successful!</h1>");
      client.println("<p>You are now logged in.</p>");
      client.println("</body>");
      client.println("</html>");
    } else {
      Serial.println("Client is unauthorized");
      client.println("HTTP/1.1 401 Unauthorized");
      client.println("WWW-Authenticate: Basic realm=\"Arduino\"");
      client.println("Content-Type: text/html");
      client.println("Connection: close");
      client.println();
      client.println("<!DOCTYPE HTML>");
      client.println("<html>");
      client.println("<head><title>401 Unauthorized</title></head>");
      client.println("<body><h1>401 Unauthorized</h1></body>");
      client.println("</html>");
    }

    // Close the connection
    delay(1);
    client.stop();
    Serial.println("Client disconnected");
  }
}

boolean checkAuthorization(WiFiClient client) {
  boolean authorized = false;

  while (client.connected()) {
    String header = client.readStringUntil('\n');
    //Serial.println(header);
    if (header.startsWith("Authorization:")) {
      String encodedCreds = header.substring(21, header.length() - 1);
      String decodedCreds = base64_decode(encodedCreds);
      String userPass = String(www_username) + ":" + String(www_password);
      if (decodedCreds.equals(userPass)) {
        authorized = true;
      }
    } else if (header == "\r") {  // Detect empty line to break
      break;
    }
  }
  return authorized;
}

String base64_decode(String input) {
  String decoded = "";
  int padding = 0;

  for (int i = 0; i < input.length(); i += 4) {
    long value = 0;
    for (int j = 0; j < 4; j++) {
      value = value << 6;
      if (input[i + j] == '=') {
        padding++;
      } else {
        if (input[i + j] >= 'A' && input[i + j] <= 'Z') {
          value += input[i + j] - 'A';
        } else if (input[i + j] >= 'a' && input[i + j] <= 'z') {
          value += input[i + j] - 'a' + 26;
        } else if (input[i + j] >= '0' && input[i + j] <= '9') {
          value += input[i + j] - '0' + 52;
        } else if (input[i + j] == '+') {
          value += 62;
        } else if (input[i + j] == '/') {
          value += 63;
        }
      }
    }
    for (int j = 0; j < 3 - padding; j++) {
      char c = (value >> ((2 - j) * 8) & 0xFF);
      decoded += c;
    }
  }
  return decoded;
}