【问题标题】:Socket IO: auth with jwt with payload套接字 IO:使用 jwt 和有效负载进行身份验证
【发布时间】:2020-12-04 07:38:45
【问题描述】:

我正在尝试在 socket.io 中间件中验证 JWT 令牌,并将 JWT 有效负载放入套接字中,以便稍后在通信时访问它,但我无法访问有效负载。

这就是我试图将 JWT 有效负载放入套接字中的方式:

var server = require('http').Server(app); // intantiating the server
var io = require('socket.io')(server);
io.use(async (socket, next) => {
    try {
        const token = socket.handshake.query.token;
        const payload = await jwt.verify(token, process.env.ACCESS_TOKEN_SECRET);
        socket.user_id = payload.user_id;
        next();
    } catch (err) {
        next(err);
    }
});

之后我可以在这里访问 user_id

io.on("connection", (socket) => {
    console.log("Connected: " + socket.user_id); // works
    socket.on("disconnect", () => {
        console.log("Disconnected: " + socket.user_id); // works
    });
});

但在这里我无法访问 user_id:

io.of('/chatroom').on('connection', function(socket) {
    socket.on('join', function() {
        console.log(socket.user_id) // null
    })
})

如何在 join 事件中获取 user_id 的值?

【问题讨论】:

    标签: node.js sockets socket.io jwt


    【解决方案1】:

    我通过像这样将中间件添加到 /chatroom 路径来解决它:

    io.use(async (socket, next) => {
        try {
            const token = socket.handshake.query.token;
            const payload = await jwt.verify(token, process.env.ACCESS_TOKEN_SECRET);
            socket.user_id = payload.user_id;
            next();
        } catch (err) {
            next(err);
        }
    });
    io.of('/chatroom').use(async (socket, next) => {
        try {
            const token = socket.handshake.query.token;
            const payload = await jwt.verify(token, process.env.ACCESS_TOKEN_SECRET);
            socket.user_id = payload.user_id;
            next();
        } catch (err) {
            next(err);
        }
    });
    

    【讨论】:

      【解决方案2】:

      一般来说,使用第三方库的内部组件来存储您自己的数据是一种不好的做法。您基本上应该将这些数据存储在某个地方,并在您的 [socketId] (实际上是 socket.io 识别通过套接字连接到服务器的用户的方式)到 [userId] (这是您识别您的用户)。

      现在,有很多实现,取决于你的可扩展性、资源、维护等。我会在这里推荐一些,你可以阅读并实现。

      1. 一个简单的 Singleton 类,您将在其中存储某种类型的一个或多个数据结构(可能是 hashmap),并且您将在 [socketId] 和 [userId] 之间进行映射。请注意,只有正在运行的进程才能在运行时获取它。

      2. 这是一个更耗费时间和资源的解决方案,但更具可扩展性。您可以使用某种内存数据库(例如 Redis)来存储这些数据。 请注意,如果您扩展应用程序,所有实例都可以从 Redis 获取数据,因为它可以接受来自您所有进程的连接。

      我相信还有更多的解决方案,但我的建议是开始实施其中一个,然后看看是否需要任何其他实施。

      【讨论】:

        猜你喜欢
        • 2016-04-30
        • 2016-08-15
        • 2016-04-20
        • 2019-08-18
        • 2016-04-07
        • 2018-02-04
        • 2017-04-27
        • 2017-11-25
        • 2023-03-27
        相关资源
        最近更新 更多