Socket.io: CORS-Fehler nach dem Update auf 2.2.0

Erstellt am 29. Nov. 2018  ·  36Kommentare  ·  Quelle: socketio/socket.io

Sie wollen:

  • [x] einen Fehler melden
  • [ ] Feature anfordern

Aktuelles Verhalten

Erhalten viele CORS-Fehler nach dem neuesten Update.
screen shot 2018-11-29 at 1 13 25 pm

Schritte zum Reproduzieren (wenn das aktuelle Verhalten ein Fehler ist)

Repo . Anweisungen finden Sie in der README-Datei.

Erwartetes Verhalten

Keine CORS-Fehler.

Konfiguration

  • Betriebssystem: Mac
  • Browser: Chrome 70
  • socket.io-Version: 2.2.0

Sonstige Informationen (z. B. Stacktraces, verwandte Probleme, Vorschläge zur Behebung)

@davericher hat hier einen Kommentar abgegeben , der darauf hinweist. Vielleicht hat er mehr Details.

Hilfreichster Kommentar

Problemumgehung: npm install socket. [email protected]

Alle 36 Kommentare

+1 Seit ich die Pakete erneut heruntergeladen habe, ist ein Fehler aufgetreten.

Problemumgehung: npm install socket. [email protected]

Das Lustige ist, dass ich einen benutzerdefinierten Ursprungsrückruf verwende und er "*" als zulässigen Ursprung zurückgibt anstelle des tatsächlichen Ursprungs, der vom Client übergeben wird, wenn der Rückruf mit Erfolg auf "true" aufgerufen wird.
In 2.1 wurde der vom Client übergebene Ursprungsheader zurückgegeben.

Hmm.. Ich sehe im Changelog nichts, was damit zu tun hat ... Es könnte das Update des ws Pakets sein.

Kann jemand das Problem reproduzieren?

Ja. Sie benötigen einen Socket-Server in einer separaten Domäne.

@darrachequesne : Ich habe meine Beschreibung mit einem Link zum Repo aktualisiert, wo Sie das Problem reproduzieren können. Anweisungen finden Sie in der README im Repo.

Ein anderer Lösungsweg: Füllen Sie die Eigenschaft origin in Ihrer Socketio-Serverkonfiguration aus:

const Server = require('socket.io');
const io = new Server({
  origins: 'http://your-cors-url' // i believe can also be an array of urls, defaults to '*'
});

Sie sollten dies in den Antwortheadern für die Handshake-Anforderung in Ihrem Netzwerk-Tab sehen:
screen shot 2018-11-29 at 4 10 28 pm

Der Browser sollte dann aufhören, sich über die CORS-Verletzung zu beschweren.

@darrachequesne Es scheint, als ob Sie diese Zeilen in engine.io-client auskommentieren :

if ('withCredentials' in xhr) {
  xhr.withCredentials = true;
}

dann sind die Anfragen erfolgreich.

Also vielleicht, in v <2.2.0, irgendwie 'withCredentials' in xhr === false ?

@sjones6 danke für das Repo. Was ich nicht verstehe, ist, dass Ihr Beispiel eine grundlegende CORS-Situation ist, in der der Client von einem anderen Standort ( localhost:3001 ) als dem Server ( localhost:3000 ) bedient wird. Das sollte in den vorherigen Versionen auch nicht funktionieren und wird, wie Sie bereits erwähnt haben, mit dem Parameter origins gelöst.

Ich denke, mit Anmeldeinformationen wurde immer auf "wahr" gesetzt.

Das Problem besteht darin, dass "Ursprünge zulassen" * nicht zulässig ist, wenn mit Anmeldeinformationen auf "true" gesetzt ist. Frühere Versionen verwendeten den Client-Ursprungsheader (oder den Referer, falls er fehlte), wenn ein Ursprung gültig war, aber die neue Version verwendet nur "*", und daher beschwert sich der Browser.

https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS/Errors/CORSNotSupportingCredentials

Eine andere Möglichkeit besteht natürlich darin, mit Anmeldeinformationen auf false zu setzen, aber das würde bedeuten, dass der Socket-IO-Server sich nicht darum kümmert, Cookies zu erhalten / zu setzen. Ich bin mir nicht sicher, ob das bei socket io der Fall ist

https://github.com/socketio/engine.io/pull/511/files#diff -c945a46d13b34fcaff544d966cffcabaL259

Dieser pr hätte eine Möglichkeit hinzufügen können, den Header auf den Ursprungsheader der Client-Anforderung zu setzen. Vielleicht ist dies ein guter Ort, um dies zu tun, wenn Origins mit einem Callback verwendet wird und der Callback mit Erfolg true aufgerufen wird, wird Allow-origins auf den Ursprung gesetzt, der an den Callback übergeben wurde.

Wie auch immer, nach dieser PR ist dies eine bahnbrechende Veränderung, obwohl ich denke?

Im Moment sehe ich keine Möglichkeit, alle Ursprünge zu unterstützen, wenn mit Anmeldeinformationen auf true gesetzt ist

Ich habe die PR rückgängig gemacht und eine neue Version von engine.io . Könnten Sie bitte überprüfen, ob es das Problem behebt? https://github.com/socketio/engine.io/commits/master

Oder um eine Breaking Change zu vermeiden, wenn Origins nicht explizit in den Optionen gesetzt / auf undefined gesetzt (Standard) oder die Origins-Funktion mit undefined aufgerufen wird, wird der Client-Origin-Header verwendet (das alte Standardverhalten).

Wäre es nicht sinnvoll, die Anmeldeinformationen standardmäßig auszuschalten? In den meisten Fällen sollte es sowieso nicht eingeschaltet sein, oder?

@darrachequesne : Danke; Wir haben 3.3.2 von engine.io heruntergezogen und die Dinge sind wieder in unserer Umgebung.

Basierend auf diesem Kommentar dieses Kommentars von @xaviergonz , denke ich, dass ich ein klareres Bild habe:

In socket.io <2.2 wurde CORS erzwungen _nur wenn_ Sie origins ; wenn nicht, waren alle Ursprünge erlaubt. In 2.2.0 (wirklich neu ab [email protected] über diesen Commit denke ich) wird CORS erzwungen, unabhängig davon, ob Sie eine Option für origins angeben oder nicht.

Ich bin ganz dafür, CORS als Standardverhalten zu erzwingen ... aber das scheint wahrscheinlich eine bahnbrechende Änderung zu sein, die in einer neuen Hauptversion hinzugefügt werden sollte.


Letzte Änderung, um die fehlerhafte Versionsnummer von engine.io zu korrigieren.

Gibt es eine ETA für die Veröffentlichung von Bugfixes? 2.2.0 verwendet Motor 3.3.1, nicht 3.3.2

@neemah ich musste
Garn socket.io entfernen && Garn socket.io hinzufügen

hier jetzt meine Garnliste:
├─ Steckdose. [email protected]
│ ├─ debug@~4.1.0
├─ [email protected]
│ └─ ms@^2.1.1
engine.io@~3.3.1
│ ├─ has-binary2@~1.0.2
├─ [email protected]
│ ├─ socket.io-adapter@~1.1.0
│ ├─ Buchse. [email protected]
└─ socket.io-parser@~3.3.0

Nun, @ravid87 ,3.3.1 engine.io ist "kaputt", während 3.3.2 behoben ist :)

@neemah der kaputte war 3.2.2

@darrachequesne : Danke; wir haben 3.2.2 von engine.io heruntergezogen und die Dinge sind wieder in unserer Umgebung.

Basierend auf diesem Kommentar dieses Kommentars von @xaviergonz , denke ich, dass ich ein klareres Bild habe:

In socket.io <2.2 wurde CORS erzwungen _nur wenn_ Sie origins ; wenn nicht, waren alle Ursprünge erlaubt. In 2.2.0 (wirklich neu ab [email protected] über diesen Commit denke ich) wird CORS erzwungen, unabhängig davon, ob Sie eine Option für origins angeben oder nicht.

Ich bin ganz dafür, CORS als Standardverhalten zu erzwingen ... aber das scheint wahrscheinlich eine bahnbrechende Änderung zu sein, die in einer neuen Hauptversion hinzugefügt werden sollte.

@ravid87 3.2.2 existiert nicht https://github.com/socketio/engine.io/tree/3.2.2 , also gehe ich davon aus, dass der Autor der Nachricht 3.3.2 gemeint hat, was die neueste Version ist, wenn Sie Commits überprüfen / Stichworte.

Warte also immer noch auf die Lösung :)

@neemah @ravid87 : Entschuldigung für die Verwirrung; Korrektur meines Tippfehlers durch Bearbeiten des Kommentars ...

@neemah: npm sollte richtig lösen [email protected] basierend auf dem deps in socket.io :

"engine.io": "~3.3.1"

Sie müssen zuerst Ihr Paket-lock.json (oder Garn.lock) löschen, aber bevor Sie es installieren, erhalten Sie erneut 3.3.1 .

@sjones6 ok thx für die Versionskorrektur. Aber ich bin immer noch verwirrt, weil
1) Auch wenn ich Garn.lock lösche, habe ich dies nach einer sauberen Installation in meinem Garn.lock (Garn entfernen socket.io, Garn sauber Cache, Garn hinzufügen socket.io):

socket.io@^2.2.0:
Version "2.2.0"
gelöst " https://registry.yarnpkg.com/socket.io/-/socket.io-2.2.0.tgz#f0f633161ef6712c972b307598ecd08c9b1b4d5b "
Integrität sha512-wxXrIuZ8AILcn+f1B4ez4hJTPG24iNgxBBDaJfT6MsyOhVYiTXWexGoPkd87ktJG8kQEcL/NBvRi64+9k4Kc0w==
Abhängigkeiten:
Debug "~4.1.0"
engine.io "~3.3.1"
has-binary2 "~1.0.2"
socket.io-Adapter "~1.1.0"
socket.io-Client "2.2.0"
socket.io-Parser "~3.3.0"

2) Ich verstehe nicht, warum mit 3.3.1 alles funktioniert...

2 - wahrscheinlich, weil Sie es auf derselben Domain überprüfen, wo dieses Problem nicht auftritt

@neemah hier mein Setup:
-> die React- App wird von
-> der Socket ist auf socket.foobar.net

Es ist also nicht in derselben Domain :/

dann haben Sie wahrscheinlich Origin mit dem Wert http[s]://foobar.com konfiguriert, wo Sie socket.foobar.net ausführen

@neemah keine Ursprünge auf socket.io oder express.js konfiguriert.

Ich hatte gestern ein CORS-Problem und heute nach einer Neuinstallation von socket.io hat alles wieder funktioniert ...

@ravid87 : Können Sie heute bestätigen, dass Sie heute [email protected] auf Ihrem Dateisystem haben? Basierend auf Ihrem Kommentar ist die Abhängigkeit von engine.io "~3.3.1" korrekt, aber die heruntergeladene Version sollte in 3.3.2 nicht in 3.3.1 . Gestern wären es 3.3.1 bis das Update veröffentlicht wurde.

yarn list --pattern engine.io --depth=5 sollte es dir sagen.

@sjones6 ja! ich habe die 3.3.2 :+1: thx für die Klarstellung :)

Ich habe das gleiche Problem mit CORS:

-- [email protected] -- Motor. [email protected]

Ich habe das gleiche Problem wie @AhCamargo , mit den gleichen Versionen von socket.io und engine.io, aber meins ist, dass ich versuche, eine socket.io-Verbindung mit Authentifizierung von einer anderen Domäne (Clientseite) als dem Server zu öffnen Seite

Vollständiger Fehlerkontext:

Serverseitige Versionen:

    "socket.io": "^2.3.0",
    "engine.io": {
      "version": "3.4.0"

Clientseitige Versionen:

    <script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.3.0/socket.io.js"></script>
  1. Kunde bei: http://localhost:5530/
    Kundencode:
      // ... get sessionToken, initialize stuff.

      var socket = io.connect('http://localhost:8011', {
        query: query,
        transportOptions: {
          polling: {
            extraHeaders: {
              'x-user-token': sessionToken
            }
          }
        }
      });

      socket.on('connect', () => {
        console.log("===> rootNspDemo connection established!!!!!, socket: ", socket.id);
      })
      socket.on('disconnect', (reason) => {
        console.log('rootNspDemo connection disconnected: ' + reason);
        socket.close(); // stop reconnecting
      })
      socket.on(topic, function(data) {
          console.log("###> root namespace progress data: ", data);
          document.getElementById("taskStatus").innerHTML = data.taskStatus;
      });
    }

Die Serverseite:

// ... imports


// Initialize express
const app = express();

// TRIED ALL THESE, BUT NONE WORK
// const cors = require('cors');
// app.use(cors({credentials: true, methods: ['GET', 'PUT', 'POST', 'PATCH', 'DELETE', 'OPTIONS']}));
// app.options('*', cors({credentials: true, methods: ['GET', 'PUT', 'POST', 'PATCH', 'DELETE', 'OPTIONS']}));
// app.use(cors());
// app.options('*', cors({methods: ['GET', 'PUT', 'POST', 'PATCH', 'DELETE', 'OPTIONS']}));

const server = app.listen(SERVER_PORT, () => {
    logInfo(
      `%s v%s listening on port %s in %s mode`,
      PKG.name,
      PKG.version,
      SERVER_PORT,
      ENV
    );
  });


// var socketIOAllowedOrigins = "http://localhost:* http://127.0.0.1:*";
var socketIOAllowedOrigins = "http://localhost:5530";

// TRIED THIS ALSO, DIDN'T WORK
// const io = require('socket.io').listen(server, {origins: socketIOAllowedOrigins});

const socketIOAuth = async function(socket, next) {
  const sessionToken = socket.handshake.headers['x-user-token'];
  const user = await getUser(sessionToken);
  if (!user) {
  // eslint-disable-next-line no-console
    console.log('---> socket ' + socket.id + ' of nsp: ' + socket.nsp.name + ' FAILED authentication !!');
    socket.disconnect('unauthorized');
    next(new Error('invalid sessionToken'));
  } else {
  // eslint-disable-next-line no-console
    console.log('---> socket ' + socket.id + ' of nsp: ' + socket.nsp.name + ' is authenticated!!');
  }

  return next();
};

const io = require('socket.io').listen(server);
io.use(socketIOAuth); // REMOVING THIS, and NOT SENDING AUTH TOKEN FROM CLIENT, THEN IT WORKS
// io.origins('*');

io.origins(['localhost:8011', 'localhost:5530',
  'http://localhost:8011', 'http://localhost:5530']);

const runDemo = (socket) => {
    // Demo test of progress bar
    // eslint-disable-next-line no-console
    console.log('Running socket.io demo for topic: ', socket.handshake.query.topic);
    let i = 0;
    const interval = setInterval(function() {
      if (i < 100) {
        socket.emit(socket.handshake.query.topic, { rootDummy: true, progress: i, taskStatus: 'RUNNING' });
        i++;
      } else {
        socket.emit(socket.handshake.query.topic, { rootDummy: true, progress: i, taskStatus: 'SUCCESS' });
        clearInterval(interval);
      }
    }, 1000);
  }

io.on('connection', runDemo);

Hier sind die interessanten Bits, die ich debuggt habe:

Entfernen der Authentifizierungs-Middleware von socketio auf der Serverseite - io.use(socketIOAuth); und Entfernen des Übergebens von sessionToken von der Clientseite:

        transportOptions: {
          withCredentials: true,
          polling: {
            extraHeaders: {
              // 'x-user-token': sessionToken
            }
          }
        }

Macht die Verbindung gut.

Ich kann das Fehlerprotokoll in nginx wie folgt sehen:

"06/Feb/2020:21:36:44 +0530" client=127.0.0.1 method=OPTIONS request="OPTIONS /socket.io/?topic=rootNspDemo&demo=true&EIO=3&transport=polling&t=N0RGEpG HTTP/1.1" request_length=574 status=400 bytes_sent=326 body_bytes_sent=54 referer=http://localhost:5530/ user_agent="Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.130 Safari/537.36" upstream_addr=127.0.0.1:8011 upstream_status=400 request_time=0.005 upstream_response_time=0.004 upstream_connect_time=0.000 upstream_header_time=0.000

curl gibt mir:

 curl -XOPTIONS 'http://local-messaging.onupkeep.com/socket.io/?topic=rootNspDemo&demo=true&EIO=3&transport=polling&t=N0RNF8q' -H 'Accept: */*' -H 'x-user-token: r:b33a941138a226f0fd37a9ea51c24c16' -H 'Referer: http://localhost:5530/' -H 'User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.130 Safari/537.36' --compressed
{"code":2,"message":"Bad handshake method"}

Was der Erklärung hier entspricht: https://stackoverflow.com/a/52048304/11626829

Grundsätzlich sendet der Browser die Optionen Pre-Flight-Request, aber das wird von socket.io als Handshake-Request aufgenommen.

ich habe das gleiche problem..

const options = { transportOptions: { polling: { extraHeaders: { 'x-auth-token': accessToken }, }, } }; socket = socketIOClient(config.socketUrl, options);

Es funktioniert gut, wenn ich es mit Abfrageparametern sende:

const options = { query:{ auth_token: accessToken } }; socket = socketIOClient(config.socketUrl, options);

ich habe das gleiche problem..

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen