Requette HTTPS avec une token - ESP-8266

Bonjour,
Je souhaite faire une requette auprès de l'API SNCF mais je ne sais pas comment envoyer mon token dans cette requette.

Ma requette actuel

client.println(F("GET /v1/coverage/sncf/stop_areas/stop_area:OCE:SA:87393421/departures? HTTP/1.0"));
  client.println(F("Host: api.sncf.com"));
  client.println(F("Connection: close"));

Si des personnes peuvent m'aider.

Mon code dans sa totalité

#include <ArduinoJson.h>
#include <ESP8266WiFi.h>

int value = 0;

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

const char* host = "api.sncf.com";
const char* streamId   = "ID";
const char* privateKey = "";

void setup() {

  Serial.begin(9600);
  delay(100);

//---Connection au WIFI----------------------

  Serial.print("Connecting to ");
  Serial.println(ssid);
  
  WiFi.begin(ssid, password);
  
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }

  Serial.println();
  Serial.println("WiFi connected");  
  Serial.print("IP address: ");
  Serial.println(WiFi.localIP());


}

void loop() {
  
  Serial.print("connexion a ");
  Serial.println(host);
  
// Cree une connexion TCP
  
  WiFiClient client;
  const int httpPort = 443;
  if (!client.connect(host, httpPort)) {
    Serial.println("connection failed");
    return;
}


// Envoi de la requette

  String url = "/input/";
  url += streamId;
  url += "?private_key=";
  url += privateKey;
  url += "&value=";
  url += value;
  
  Serial.print("Requesting URL: ");
  Serial.println(url);
  
  client.println(F("GET /v1/coverage/sncf/stop_areas/stop_area:OCE:SA:87393421/departures? HTTP/1.0"));
  client.println(F("Host: api.sncf.com"));
  client.println(F("Connection: close"));
  unsigned long timeout = millis();
  while (client.available() == 0) {
    if (millis() - timeout > 5000) {
      Serial.println("  Timeout !");
      Serial.println();
      client.stop();
      return;
}
}
    while(client.available()){
    String line = client.readStringUntil('\r');
    Serial.print(line);
    }
  
    delay(1000);


}

Vous avez essayé
https://########@api.sncf.com/v1/coverage/sncf/stop_areas/stop_area:OCE:SA:87393421/departures?

Ou les #### sont le token obtenu sur leur site?

(Virez le mot de passe du wifi dans votre code précédent)

En utilsant cette requette, même réponse : Timeout

 client.println(F("GET https://*TOKEN*@api.sncf.com/v1/coverage/sncf/stop_areas/stop_area:OCE:SA:87393421/departures? HTTP/1.1"));
  client.println(F("Host: api.sncf.com"));
  client.println(F("Connection: close"));

si vous tapez dans un navigateur web

https://*TOKEN*@api.sncf.com/v1/coverage/sncf/stop_areas/stop_area:OCE:SA:87393421/departures?

ça vous dit quoi?

J ai le résultat souhaité

Le timeout pourrais t'il être causé par le type de ficher théoriquement reçu en json ?

je viens de voirclient.println(F("Connection: close"));ce n’est pas une syntaxe HTTP correcte, il manque une ligne vide juste après , essayez avec un

  client.println(F("GET https://*TOKEN*@api.sncf.com/v1/coverage/sncf/stop_areas/stop_area:OCE:SA:87393421/departures? HTTP/1.1"));
  client.println(F("Host: api.sncf.com"));
  client.println(F("Connection: close"));
  client.println();

J-M-L:
Si vous essayez depuis un navigateur qui n’a jamais été connecté Au site de la sncf est-ce que ça fonctionne aussi?

Une ouverture de session est demandé sur Edge et chrome, pas sur firefox

J-M-L:
je viens de voirclient.println(F("Connection: close"));ce n’est pas une syntaxe HTTP correcte, il manque une ligne vide juste après , essayez avec un

  client.println(F("GET https://*TOKEN*@api.sncf.com/v1/coverage/sncf/stop_areas/stop_area:OCE:SA:87393421/departures? HTTP/1.1"));

client.println(F("Host: api.sncf.com"));
  client.println(F("Connection: close"));
  client.println();

Ne fonctionne toujours pas

Vous pouvez essayer la requête http depuis un navigateur qui s’est jamais connecté au site de la sncf pour voir s’il ny a pas un login/pwd à remplir qui serait dans une session active sur celui que vous avez essayé ??

Oui il y en a un avec un navigateur jamais utiliser

Peut-être qu'il ne faut pas utiliser F(...)

Le F() fonctionne pas de soucis

Au fait vous avez quelle librairie ESP8266WiFi.h ?

Et Je viens aussi de voir que c’était du https... faut passer en WiFiClientSecure...et il vous faudra le SHA1 du fingerprint du serveur (trouvable avec votre navigateur qui a pu se connecter)

En utilisant HTTPSRequest - Fourni avec ma librairie ESP2688 -

J'ai une réponse, mais je n'ai visiblement pas réussi a envoyé ma token

reply was:
==========
{"message":"no token. You can get one at http:\/\/www.navitia.io or contact your support if you\u2019re using the opensource version of Navitia https:\/\/github.com\/CanalTP\/navitia"}
==========
closing connection

postez votre code en masquant le token

J'ai aidé un "collègue" sur le forum anglo saxon ici : ça peut peut-être aider (bien que le site consulté soit en http pas en https mais il est peut-être possible de s’en inspirer quand même)

/*
 *  HTTP over TLS (HTTPS) example sketch
 *
 *  This example demonstrates how to use
 *  WiFiClientSecure class to access HTTPS API.
 *  We fetch and display the status of
 *  esp8266/Arduino project continuous integration
 *  build.
 *
 *  Created by Ivan Grokhotkov, 2015.
 *  This example is in public domain.
 */

#include <ESP8266WiFi.h>
#include <WiFiClientSecure.h>

const char* ssid = "SSID";
const char* password = "******";

const char* host = "api.sncf.com";
const int httpsPort = 443;

// Use web browser to view and copy
// SHA1 fingerprint of the certificate
const char* fingerprint = "95 59 EC 9A C3 2F 8D 95 D0 E0 4A D6 B9 D9 EE B8 B1 4F DD B0";

void setup() {
  Serial.begin(9600);
  Serial.println();
  Serial.print("connecting to ");
  Serial.println(ssid);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());

  // Use WiFiClientSecure class to create TLS connection
  WiFiClientSecure client;
  Serial.print("connecting to ");
  Serial.println(host);
  if (!client.connect(host, httpsPort)) {
    Serial.println("connection failed");
    return;
  }

  if (client.verify(fingerprint, host)) {
    Serial.println("certificate matches");
  } else {
    Serial.println("certificate doesn't match");
  }

  client.println(F("GET  https://*TOKEN*@api.sncf.com/v1/coverage/sncf/stop_areas/stop_area:OCE:SA:87393421/departures? HTTP/1.1"));
  client.println(F("Host: api.sncf.com"));
  client.println(F("Connection: close")); // keep alive
  client.println();

  Serial.println("request sent");
  while (client.connected()) {
    String line = client.readStringUntil('\n');
    if (line == "\r") {
      Serial.println("headers received");
      break;
    }
  }
  String line = client.readStringUntil('\n');
  if (line.startsWith("{\"state\":\"success\"")) {
    Serial.println("esp8266/Arduino CI successfull!");
  } else {
    Serial.println("esp8266/Arduino CI has failed");
  }
  Serial.println("reply was:");
  Serial.println("==========");
  Serial.println(line);
  Serial.println("==========");
  Serial.println("closing connection");
}

void loop() {
}

le SHA1 semble correct mais Votre requête GET est mal écrite, elle contient l'URI entière.

Essayez avec cela (en mettant votre token et en le virant du post précédent)

#include <ESP8266WiFi.h>
#include <WiFiClientSecure.h>

const char* ssid = "SSID";
const char* password = "******";

const char* host = "{VOTRE TOKEN}@api.sncf.com";
const int httpsPort = 443;

// Use web browser to view and copy
// SHA1 fingerprint of the certificate
const char* fingerprint = "95 59 EC 9A C3 2F 8D 95 D0 E0 4A D6 B9 D9 EE B8 B1 4F DD B0";

void setup() {
  Serial.begin(9600);
  Serial.println();
  Serial.print("connecting to ");
  Serial.println(ssid);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());

  // Use WiFiClientSecure class to create TLS connection
  WiFiClientSecure client;
  Serial.print("connecting to ");
  Serial.println(host);
  if (!client.connect(host, httpsPort)) {
    Serial.println("connection failed");
    return;
  }

  if (client.verify(fingerprint, host)) {
    Serial.println("certificate matches");
  } else {
    Serial.println("certificate doesn't match");
  }

  client.println(F("GET /v1/coverage/sncf/stop_areas/stop_area:OCE:SA:87393421/departures? HTTP/1.1"));
  client.println(F("Host: api.sncf.com"));
  client.println(F("User-Agent: ESP32-cfresse"));
  client.println(F("Connection: close")); // keep alive
  client.println();

  Serial.println("request sent");

  while (client.connected()) {
    String line = client.readStringUntil('\n');
    if (line == "\r") {
      Serial.println("headers received");
      break;
    }
  }
  String line = client.readStringUntil('\n');
  if (line.startsWith("{\"state\":\"success\"")) {
    Serial.println("esp8266/Arduino CI successfull!");
  } else {
    Serial.println("esp8266/Arduino CI has failed");
  }
  Serial.println("reply was:");
  Serial.println("==========");
  Serial.println(line);
  Serial.println("==========");
  Serial.println("closing connection");
}

void loop() {
}

Je n'arrive pas a me connecter avec ce host

const char* host = "{VOTRE TOKEN}@api.sncf.com";

Voici la réponse

connecting to *TOKEN*@api.sncf.com
connection failed

pas surprenant mais fallait essayer pour voir si c'était intelligent :slight_smile:

va falloir sans doute passer le token dans le header - suis sur mobile pour le moment, je regarderai un peu plus tard

En cherchant sur le site NAVITIA (base de l'api SNCF) j'ai trouvé cela

3 ways to request Navitia

#using "headers"
$ curl 'https://api.navitia.io/v1/coverage' -H 'Authorization: 3b036afe-0110-4202-b9ed-99718476c2e0'

#using "users": don't forget ":" at the end of line !
$ curl https://api.navitia.io/v1/coverage -u 3b036afe-0110-4202-b9ed-99718476c2e0:

#using "straight URL"
$ curl https://3b036afe-0110-4202-b9ed-99718476c2e0@api.navitia.io/v1/coverage

Neanmois, en modifiant ma requette

client.println(F("GET /v1/coverage/sncf/stop_areas/stop_area:OCE:SA:87393421/departures? HTTP/1.1"));
  client.println(F("Host: api.sncf.com"));
  client.println(F("User-Agent: ESP32-cfresse"));
  client.println(F("Autorization: 3b036afe-0110-4202-b9ed-99718476c2e0"));
  client.println();

Toujours la même réponse :"No token"
Cela peux peut être vous aider
(ce sont de fausse token)