【问题标题】:Authenticating socket io connections using JWT使用 JWT 验证套接字 io 连接
【发布时间】:2016-08-15 18:57:26
【问题描述】:

如何验证 socket.io 连接?我的应用程序使用来自另一台服务器 (python) 的登录端点来获取令牌,每当用户在节点端打开套接字连接时,我如何才能使用该令牌?

io.on('connection', function(socket) {
    socket.on('message', function(message) {
        io.emit('message', message);
    });
});

和客户端:

var token = sessionStorage.token;
var socket = io.connect('http://localhost:3000', {
    query: 'token=' + token
});

如果令牌是在python中创建的:

token = jwt.encode(payload, SECRET_KEY, algorithm='HS256')

如何使用此令牌来验证节点中的套接字连接?

【问题讨论】:

    标签: node.js socket.io jwt token


    【解决方案1】:

    令牌是否在另一台服务器上创建无关紧要。如果您拥有正确的密钥和算法,您仍然可以验证它。

    jsonwebtoken模块实现

    客户

    const {token} = sessionStorage;
    const socket = io.connect('http://localhost:3000', {
      query: {token}
    });
    

    服务器

    const io = require('socket.io')();
    const jwt = require('jsonwebtoken');
    
    io.use(function(socket, next){
      if (socket.handshake.query && socket.handshake.query.token){
        jwt.verify(socket.handshake.query.token, 'SECRET_KEY', function(err, decoded) {
          if (err) return next(new Error('Authentication error'));
          socket.decoded = decoded;
          next();
        });
      }
      else {
        next(new Error('Authentication error'));
      }    
    })
    .on('connection', function(socket) {
        // Connection now authenticated to receive further events
    
        socket.on('message', function(message) {
            io.emit('message', message);
        });
    });
    

    socketio-jwt模块实现

    此模块使客户端和服务器端的身份验证更加容易。看看他们的例子吧。

    客户

    const {token} = sessionStorage;
    const socket = io.connect('http://localhost:3000');
    socket.on('connect', function (socket) {
      socket
        .on('authenticated', function () {
          //do other things
        })
        .emit('authenticate', {token}); //send the jwt
    });
    

    服务器

    const io = require('socket.io')();
    const socketioJwt = require('socketio-jwt');
    
    io.sockets
      .on('connection', socketioJwt.authorize({
        secret: 'SECRET_KEY',
        timeout: 15000 // 15 seconds to send the authentication message
      })).on('authenticated', function(socket) {
        //this socket is authenticated, we are good to handle more events from it.
        console.log(`Hello! ${socket.decoded_token.name}`);
      });
    

    【讨论】:

    • 我遇到了一个问题,即使没有到套接字的传入连接,当我启动套接字服务器时,它仍然有旧令牌。这很奇怪吗?
    • 如果用户最初未经授权并且在第一次尝试时没有密码,您将如何重新连接到服务器?
    • 你好,我想问一下,在连接或每次发射事件时都需要一次令牌?
    • 不完全相关,但是您从存储在 sessionStorage.token 中的端点收到的令牌?这意味着在您的页面上运行的任何 JS 都可以访问令牌对吗?是什么阻止了外部 JS 代码(如 chrome 扩展)读取令牌并使用它来登录自己的套接字,就好像他们是你一样?这就像一个带有 HttpOnly:false 的 cookie 来存储您的访问权限。我也试图通过来自外部服务器的令牌来识别套接字连接,但是我还没有找到一种方法来在令牌到达客户端后对其保密,因为任何(其他外部)JS 也可以读取它。 :( 有什么想法吗?
    • 对于任何获得Cannot read property 'on' of undefined的人;只需从function(socket) 中删除socket
    猜你喜欢
    • 2016-04-30
    • 2020-12-04
    • 1970-01-01
    • 2021-12-24
    • 2020-05-03
    • 2017-03-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多