Подтвердить что ты не робот

Отправить пользовательские данные вместе с handshakeData в socket.io?

Итак, у меня есть приложение, работающее под node js с socket.io как бэкэнд и обычный javascript в качестве интерфейса. Мое приложение имеет систему входа в систему, в которой в настоящее время клиент просто отправляет свои данные для входа сразу после подключения.

Теперь я понял, что было бы гораздо приятнее иметь данные для входа, отправленные вместе с handshakeData, поэтому я могу напрямую подключиться к пользователю при подключении (а не после установления соединения) соответственно отказаться от авторизации, когда данные входа недействительны.

Я думаю, что было бы лучше поместить мои дополнительные данные в заголовочную часть рукопожатия, так что любые идеи, как я мог это сделать? (Без необходимости изменять socket.io, если это возможно, но если это единственный способ, которым я могу жить с ним)

4b9b3361

Ответ 1

Как уже было сказано много комментариев, API Socket.IO изменился в версии 1.0. Теперь аутентификация должна выполняться с помощью функции промежуточного программного обеспечения, см. "Различия в аутентификации" @http://socket.io/docs/migrating-from-0-9/#authentication-differences. Я включу свой первоначальный ответ для тех, кто застрял на < 1.0, поскольку старые документы, похоже, исчезли.

1.0 и более поздние версии:

Сторона клиента:

//The query member of the options object is passed to the server on connection and parsed as a CGI style Querystring.
var socket = io("http://127.0.0.1:3000/", { query: "foo=bar" });

Сторона сервера:

io.use(function(socket, next){
    console.log("Query: ", socket.handshake.query);
    // return the result of next() to accept the connection.
    if (socket.handshake.query.foo == "bar") {
        return next();
    }
    // call next() with an Error if you need to reject the connection.
    next(new Error('Authentication error'));
});

Pre 1.0

Вы можете передать запрос: param во втором аргументе connect() на стороне клиента, который будет доступен на сервере в методе авторизации.

Я только что тестировал его. На клиенте у меня есть:

var c = io.connect('http://127.0.0.1:3000/', { query: "foo=bar" });

На сервере:

io.set('authorization', function (handshakeData, cb) {
    console.log('Auth: ', handshakeData.query);
    cb(null, true);
});

Результат на сервере выглядел так:

:!node node_app/main.js
   info  - socket.io started
Auth:  { foo: 'bar', t: '1355859917678' }

Ответ 2

Теперь это было изменено в версии 1.0. См. документы о миграции

в основном,

io.set('authorization', function (handshakeData, callback) {
  // make sure the handshake data looks good
  callback(null, true); // error first, 'authorized' boolean second 
});

становится:

  io.use(function(socket, next) {
  var handshakeData = socket.request;
  // make sure the handshake data looks good as before
  // if error do this:
    // next(new Error('not authorized');
  // else just call next
  next();
});

Ответ 3

Для socket.io v1.2.1 используйте это:

io.use(function (socket, next) {
  var handshake = socket.handshake;
  console.log(handshake.query);
  next();
});

Ответ 4

Этот мой код для отправки данных запроса узлам и серверу server.io.

var socket = io.connect(window.location.origin, { query: 'loggeduser=user1' });

io.sockets.on('connection', function (socket) {
    var endp = socket.manager.handshaken[socket.id].address;
    console.log("query... " + socket.manager.handshaken[socket.id].query.user);
}

Ответ 5

Возможно, api изменился, но я сделал следующее, чтобы получить дополнительную информацию на сервере.

// client
io.connect('localhost:8080', { query: 'foo=bar', extra: 'extra'});

// server
io.use(function(sock, next) {
  var handshakeData = sock.request;
  console.log('_query:', handshakeData._query);
  console.log('extra:', handshakeData.extra);
  next();
});

печатает

_query: { foo: 'bar',
  EIO: '3',
  transport: 'polling',
  t: '1424932455409-0' }
extra: undefined

Если кто-нибудь знает, как получить данные от клиента на сервер через рукопожатие, которое не входит в параметры запроса, дайте мне знать.

Обновление Я столкнулся с проблемами позже с этим синтаксисом

io.connect('localhost:8080?foo=bar');

- это то, что я сейчас использую.

Ответ 6

Я нашел небольшую проблему, чтобы увидеть .loggeduser

io.sockets.on('connection', function (socket) {
    var endp = socket.manager.handshaken[socket.id].address;
    console.log("query... " + socket.manager.handshaken[socket.id].query.loggeduser);
                                                                         // ↑ here
}

Ответ 7

Старый поток, но при условии, что вы сохраняете свой идентификатор токена/сеанса jwt в файлах cookie сеанса (стандартные вещи), они все равно передаются на сервер по умолчанию при выполнении рукопожатия (socket.io-client), который я заметил. Что-то не так с получением информации об аутентификации для рукопожатия (через промежуточное ПО или on.connection) через cookie? например.

io.on('connection', function(socket) {
  // assuming base64url token
  const cookieStr = socket.handshake.headers.cookie
  const matchRes =
    cookieStr == null
      ? false
      : cookieStr.match(/my-auth-token=([a-zA-Z0-9_.-]+)/)
  if (matchRes) {
    // verify your jwt...
    if ( tokenIsGood(matchRes[1]) {
      // handle authenticated new socket
    } else {
      socket.emit('AUTH_ERR_LOGOUT')
      socket.disconnect()
    }
  } else {
    socket.emit('AUTH_ERR_LOGOUT')
    socket.disconnect()
  }
}

Я использую это сейчас для проекта, и он работает нормально.