【问题标题】:Emitting data only to authenticated user with socket.io使用 socket.io 仅向经过身份验证的用户发送数据
【发布时间】:2018-07-11 14:17:28
【问题描述】:

我有一个带有 nodejs 后端的 Web 应用程序,它需要通过套接字与移动应用程序通信。 Web 应用程序有一个注册/登录系统,在标头中集成了 JWT。

我想做的是: 假设用户已登录网络应用程序。

  1. 用户从网络应用发送一个套接字

     sendSomething(add) {
    this.socket.emit('add', add);
    console.log(add);
    

    }

  2. 服务器接收它,将其发送到移动应用程序

    io.on('connection', (socket) => {
    console.log('user connected');
    
    socket.on('disconnect', function() {
        console.log('user disconnected');
    });
    
    socket.on('add', (add) => {
        io.emit('message', {type: 'new-add', text: add});
        console.log(add);
    })
    

    });

  3. 移动应用对数据进行处理。

    ngOnInit() {
    this.socket.on('message', function(socket, message) {
        console.dir(socket, message);
    })
    }
    

我的问题是,我只想向具有与特定用户登录的 Web 应用程序相同的身份验证的移动应用程序发送“消息”事件。

因此,如果我以以下身份登录 WEB 应用程序:example@example.com / somepassword 我只想将消息事件发送到用户使用相同凭据登录的移动应用程序。

我该怎么做?

谢谢,

【问题讨论】:

    标签: javascript android node.js sockets socket.io


    【解决方案1】:

    对于那些仍然想知道如何做到这一点的人,这里有一个代码示例:

        const socketjwtauth = require("socketio-jwt-auth")
        io.use(socketjwtauth.authenticate({
        secret: "anythingstrong", //literally keep it strong in the .env file
        }, async function (payload, done) {
           console.log("sdjsndsadnkajnk")
           console.log(payload.email)
        }))
    
        //check for the user email from payload against your database
    
        io.on('connection', function (socket) {
        console.log('Authentication passed!');
         //now you can access user info through socket.request.user
        //socket.request.user.logged_in will be set to true if the user was authenticated
        socket.emit('success', {
           message: 'success logged in!',
           user: socket.request.user,
           status: socket.request.user.logged_in
        });
       })
    

    基本上我们所做的是为我们的套接字创建一个身份验证中间件,只有在身份验证通过时才会连接用户。

    【讨论】:

      【解决方案2】:

      在 socket.io 中,当一个套接字打开并连接到您的服务器时,它会一直保持到断开连接为止,所以你的解决方案是:

      只需替换这一行:

      io.emit('message', {type: 'new-add', text: add});
      

      用这个:

      socket.emit('message', {type: 'new-add', text: add});
      

      并且您的 message 事件会在与登录完全相同的用户中触发。

      希望我能解决你的问题,这个答案会对你有所帮助!

      【讨论】:

        【解决方案3】:

        您必须通过会话密钥或任何其他唯一 ID 来管理套接字连接。基本上,您必须管理具有唯一 ID 的连接,以便在需要时找到特定的连接。

        让我们假设abc@gmail.com 的用户登录了一个网站并连接到服务器。因此,服务器端您将获得abc@gamil.com 用户的新连接,因此我们可以存储名称为abc@gmail.com-web 的连接。手机abc@gmail.com-mobile也一样。

        现在我们有两个来自不同平台的同一用户的连接,因此当用户从web 发送消息时,我们可以使用连接abc@gmail.com-mobile 将此消息转发到mobile

        更深入:

        如果您使用 NodeJs 作为后端,那么您可以使用中间件来进行 JWT 并验证哪个用户已连接。也可以使用开源库(我从未尝试过)https://github.com/adcentury/socketio-jwt-auth

        【讨论】:

        • 对。这正是我要问的。但是由于我仍然是后端新手,您能否指出一个代码示例,我可以在其中看到它是如何实现的?
        • 如果您想了解更多详细信息,那么我需要知道您的技术堆栈是哪种技术以及您是如何使用的。@FilipBarakovski
        • 嘿@pathikdevani,我在后端使用 NodeJS + MongoDB(mongoose),在 web 上使用 Angular 2,在移动应用上使用 NativeScript。
        • 试试这个github.com/adcentury/socketio-jwt-auth它最适合你的堆栈
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-12-22
        • 2016-01-15
        • 1970-01-01
        • 2019-11-10
        • 2017-11-15
        • 2018-11-07
        • 2020-11-15
        相关资源
        最近更新 更多