60

したがって、バックエンドとしてsocket.ioを使用し、フロントエンドとして通常のjavascriptを使用してノードjsを実行するアプリケーションがあります。私のアプリケーションにはログインシステムがあり、現在、クライアントは接続されるとすぐにログインデータを送信します。

ログインデータをhandshakeDataと一緒に送信すると、接続中に(接続を確立した後ではなく)ユーザーに直接ログインさせ、ログインデータが無効な場合に認証を拒否することができます。

追加のデータをhandshakeDataのヘッダー部分に配置するのが最善だと思います。それで、どうすればそれができるのでしょうか。(可能であればsocket.ioを変更する必要はありませんが、それが私がそれと一緒に暮らすことができる唯一の方法である場合)

4

7 に答える 7

147

以下で多くのコメントが指摘されているように、Socket.IOAPIは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'));
});

1.0より前

2番目の引数にquery: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' }

アップデート

3.x以降

クライアント側のconnect()の2番目の引数としてauth paramを使用して、認証ペイロードを渡すことができます。

クライアント側:

io.connect("http://127.0.0.1:3000/", {
    auth: {
      token: "AuthToken",
    },
  }),

サーバー側では、を使用してアクセスできますsocket.handshake.auth.token

サーバ側:

io.use(function(socket, next){
    console.log(socket.handshake.auth.token)
    next()
});
于 2012-12-18T19:48:54.470 に答える
19

これはv1.0.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();
});
于 2014-09-24T14:12:22.423 に答える
10

socket.io v1.2.1の場合、これを使用します。

io.use(function (socket, next) {
  var handshake = socket.handshake;
  console.log(handshake.query);
  next();
});
于 2014-12-22T15:31:52.207 に答える
7

これは、nodejsおよび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);
}
于 2014-03-29T20:07:28.067 に答える
1

おそらく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');

私が現在使用しているものです。

于 2015-02-26T06:39:20.940 に答える
1

古いスレッドですが、jwtトークン/セッションIDをセッションCookie(標準のもの)に保存すると仮定すると、ハンドシェイク(socket.io-client)を実行すると、デフォルトでサーバーに渡されます。Cookieを介して(ミドルウェアまたはon.connectionを介して)ハンドシェイクの認証情報を取得するだけで何か問題がありますか?例えば。

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()
  }
}

私は今これをプロジェクトに使用していますが、正常に機能しています。

于 2019-01-26T06:51:05.310 に答える
0

.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
}
于 2014-05-27T01:16:02.567 に答える