【问题标题】:Reconnect disconnected socket.io with JWT authentication使用 JWT 身份验证重新连接断开的 socket.io
【发布时间】:2020-07-14 19:26:50
【问题描述】:

我正在使用 JWT 对 socket.io 进行身份验证。这是客户端代码:

const socket = io.connect(
            'ws://123.456.789.0:8500',
            {
                query: {
                    token: jwtToken
                },
                transports: ['websocket', 'polling']
            }
        );

现在,jwtToken 会在某个时候过期,并且与 服务器 的连接断开:

...
io.on('connection', async (socket) => {
    const isExpired = await checkExpireDateEveryMinute(socket.exp, 5);

    if (isExpired) {
        socket.disconnect();
    }

    await socket.on('query', async (data) => {

        ...

    });
});

使用新生成的 JWT 令牌从客户端重新连接的正确方法是什么?在这方面找不到太多资源。谢谢。

【问题讨论】:

    标签: javascript socket.io jwt


    【解决方案1】:

    我认为另一种方法是使用 socket.io 的中间件功能,如果您使用 Error 对象调用 next(),它将阻止 on("connection") 回调触发。它还将错误消息传输到前端。您可以通过这种方式发送一个新的令牌,然后重新连接。

    这是一个例子:

    async function authenticate(socket,next){
        const isExpired = await checkExpireDateEveryMinute(socket.exp, 5);
    
        if(isExpired){
            const newToken = getNewToken()//Get a new token...
            next(new Error(newToken))//This will cause an error in your frontend, and pass the new token.
        }else{
            next();
        }
    }
    io.use(authenticate)//Register the middleware.
    

    我必须指出一点:你在 socket.on(query,...) 上做“等待”,这是没有意义的。

    至于你的前端,它可能看起来像这样:

    function initSocket(token, url) {
    
      const socket = io.connect(url, {//Init the socket.
        query: {
          token
        }
      });
    
      return socket;
    }
    
    let socket = initSocket('someToken', 'http://localhost:8000')
    
    socket.on('error', async (error) => {
      if(error === 'TOKEN_EXPIRED'){
        const newToken = await getToken();
        socket.close();
        socket = initSocket(newToken, 'http://localhost:8000')
      }
    })
    

    请注意,您需要重新注册您的套接字的所有事件。

    【讨论】:

    • 感谢您的回答!实际上,我通过 AJAX 请求从另一个后端获取令牌,并从前端通过 node.js 服务器发送。但是,如果我们按照逻辑,我应该在不关闭连接的情况下向前端发送令牌过期错误,而从前端我只是 socket.emit 新令牌?对吗?
    • 一旦你得到这个错误,你只需要调用你的套接字启动函数(假设你有一个),传递新的令牌,然后重新连接。它将是一个带有新凭据的新套接字。
    • 过期时间来自服务器(无论是什么服务器)。你的解决方案行不通。
    猜你喜欢
    • 2019-05-23
    • 2018-08-03
    • 1970-01-01
    • 2018-07-19
    • 1970-01-01
    • 2018-12-21
    • 1970-01-01
    • 2013-11-21
    • 1970-01-01
    相关资源
    最近更新 更多