Socket.io-client: السماح باستعلام socket.handshake.query ليكون دالة

تم إنشاؤها على ٢٢ مايو ٢٠١٧  ·  9تعليقات  ·  مصدر: socketio/socket.io-client

اتريد:

  • [x] أبلغ عن خطأ
  • [] طلب ميزة

السلوك الحالي

يسمح socket.handshake.query حاليًا بتعيين البيانات على connect ، لكن لا يمكن تحديثها بالمرجع قبل إطلاق reconnect . يتسبب هذا في مشكلة عند السماح باتصال مأخذ برموز التحديث.

خطوات إعادة الإنتاج (إذا كان السلوك الحالي خطأ)

//client
io.connect("wss://socket.server.com", {
   query : {
      token:"something dynamic"
   }
});

إذا تم إعادة تشغيل الخادم وعملاء reconnect ، فقد يكون الرمز المميز قديمًا عند إعادة تفويض المقبس.

//server
io.use(function(socket, next) {
   var query = socket.handshake.query;
   if(isValidToken(query.token)){
      next();//will never fire if the token has been updated
   }
});

سلوك متوقع

السماح للاستعلام أن يكون function :

io.connect("wss://socket.server.com", {
   query : function(){
      return {
         token:"something dynamic"
      }
   }
});

يثبت

  • الإصدار socket.io: 2.0.1

كيفية الإصلاح

في مُنشئ المقبس الحالي:

if (opts && opts.query) {
   this.query = opts.query;
}

يمكن تغييره إلى هذا:

if(opts && opts.query) {
   this.query = typeof opts.query == 'function' && opts.query.call(this) || opts.query;
}

التعليق الأكثر فائدة

reeltimedoktor حاليا يجب أن تكون قادرا على تحديث query الكائن على reconnect_attempt الحدث:

socket.on('reconnect_attempt', function () {
  socket.io.opts.query = { token: /* ... */ };
});

ال 9 كومينتر

+1
إصلاح الخطأ رقم 1086 يجب أن يحل مشكلتك أيضًا. كان تغيير خيارات الاستعلام بعد الاتصال الناجح يعمل مع إصدار أقدم من socket.io-client ، ولكن مع الإصدار الحالي يتم فقد المرجع إلى كائن الاستعلام :(

reeltimedoktor حاليا يجب أن تكون قادرا على تحديث query الكائن على reconnect_attempt الحدث:

socket.on('reconnect_attempt', function () {
  socket.io.opts.query = { token: /* ... */ };
});

يبدو أن حل darrachequesne لا يعمل بالنسبة لي :(

أنا أستخدم socket.io-client version 2.3.0 على العميل ، مع خادم عقدة بإصدار socket.io 2.3.0 .

بالنسبة للعميل الذي أفعله:

 socket.on('reconnect_attempt', async () => {
      const newToken = await getNewToken();
      socket.io.opts.query = {
        token: latestToken,
      };
    });

وبعد ذلك يقوم الخادم بمصادقة الرمز المميز باستخدام برنامج وسيط تم تمريره إلى io.use() (والذي يجب تشغيله بعد ذلك عند توصيل المقبس أو إعادة الاتصال ، afaik؟).

في الوقت الحالي ، تفشل مصادقة الخادم في إعادة الاتصال ، قائلة إن الرمز المميز قد انتهى - يبدو أن الرمز المميز الجديد لم يتم تعيينه بشكل صحيح إلى socket.io.opts.query.token - أي أفكار لماذا؟

شكرا :)

تحديث: يبدو أن هناك مجموعة من الأماكن المختلفة في كائن المقبس حيث يتم تخزين رمز المصادقة ، على سبيل المثال socket.io.engine.query.token ، socket.io.engine.transport.query.token . لا يتم ملؤها تلقائيًا عند تعيين socket.io.opts.query.token . ومع ذلك ، فإن تغيير هذه لا يزال لا يؤثر على ما "تراه" الخوادم - فهي لا تزال ترى الرمز القديم فقط.

يبدو أيضًا أنه تم تضمين الرمز المميز كمعامل URL في بعض حقول عنوان url في كائن المقبس. ربما هذه تحتاج إلى التحديث أيضا؟

بعد التحقيق أبعد من ذلك، يبدو أن وضع مميز على socket.io.opts.query.token غير كافية لتغيير رمز لإعادة المصادقة على اعادة ربط - يبدو شيء آخر أن المشكلة لبلدي التطبيق، وربما أن تفعل شيئا مع firebase المصادقة جيل رمزي. لذلك بالنسبة لأي شخص آخر يصادف هذا ، darrachequesne يعمل!

حسنًا ، أعتقد أنني قمت بإصلاحه - تحتاج إلى التأكد من حصولك على الرمز المميز الجديد بشكل متزامن في رد الاتصال "recnect_attempt" ، أي لا تفعل هذا:

 socket.on('reconnect_attempt', async () => {
      const newToken = await getNewToken(); // won't work
      socket.io.opts.query = {
        token: latestToken,
      };
    });

يبدو أنه تم إجراء المصادقة من جانب الخادم قبل تعيين الرمز المميز الجديد. إذا حصلت على الرمز المميز بشكل متزامن (عن طريق الحصول عليه في وقت سابق وتخزينه ، ثم استعادته فقط في رد اتصال المستمع) ، يحصل الخادم على رمز المصادقة الجديد في الوقت المناسب لإعادة مصادقة الاتصال.

مع "socket.io-client": "3.0.4" يظهر لي خطأ TS2341: Property 'opts' is private and only accessible within class 'Manager'. . أنا أستخدم "typescript": "4.1.3"
image

حسنًا ، أعتقد أنني قمت بإصلاحه - تحتاج إلى التأكد من حصولك على الرمز المميز الجديد _synchronually_ في رد الاتصال "recnect_attempt" ، أي لا تفعل هذا:

 socket.on('reconnect_attempt', async () => {
      const newToken = await getNewToken(); // won't work
      socket.io.opts.query = {
        token: latestToken,
      };
    });

يبدو أنه تم إجراء المصادقة من جانب الخادم قبل تعيين الرمز المميز الجديد. إذا حصلت على الرمز المميز بشكل متزامن (عن طريق الحصول عليه في وقت سابق وتخزينه ، ثم استعادته فقط في رد اتصال المستمع) ، يحصل الخادم على رمز المصادقة الجديد في الوقت المناسب لإعادة مصادقة الاتصال.

لدينا مشكلة مماثلة. لكن الحل الحالي هو الحصول على disconnect من جانب الخادم عندما تفشل المصادقة. عند تلقي حدث disconnect على العميل ، نقوم بإعادة بناء الاستعلام / الرأس باستخدام استدعاء الوعد غير المتزامن. بحلول الوقت الذي يصل فيه إلى الحدث reconnecting ، يكون لديه بالفعل القيمة الجديدة في الاستعلام / العنوان.

لقراء المستقبل:

سلوك الخيار query في Socket.IO v2 غريب بعض الشيء ، حيث يتم استخدامه في كليهما:

  • معلمات الاستعلام (لمثيل المدير)
  • مصافحة Socket.IO (ولكن فقط لمساحة اسم غير افتراضية)

لذلك لست متأكدًا من كيفية إصلاحه بطريقة متوافقة مع الإصدارات السابقة ...

يرجى ملاحظة أن هذا تم إصلاحه في Socket.IO v3 ، حيث يمكنك الآن استخدام الخيار auth :

// plain object
const socket = io({
  auth: {
    token: "abc"
  }
});

// or with a function
const socket = io({
  auth: (cb) => {
    cb({
      token: "abc"
    });
  }
});

يجب أن تعمل مع وظيفة async أيضًا:

const socket = io({
  auth: async (cb) => {
    cb({
      token: "abc"
    });
  }
});

أنظر أيضا:

هل كانت هذه الصفحة مفيدة؟
0 / 5 - 0 التقييمات