简体   繁体   English

使用 socket.io 仅向经过身份验证的用户发送数据

[英]Emitting data only to authenticated user with socket.io

I have an web application with a nodejs backend, that needs to communicate with a mobile application via sockets.我有一个带有 nodejs 后端的 Web 应用程序,它需要通过套接字与移动应用程序进行通信。 The web application has a register/login system integrated with JWT in the headers. Web 应用程序在标头中有一个与 JWT 集成的注册/登录系统。

What I want to do is this: Let's assume the user is logged in on the web app.我想要做的是:让我们假设用户已登录 Web 应用程序。

  1. The user sends a socket from the web app用户从 Web 应用程序发送套接字

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

    } }

  2. Server recieves it, sends it to mobile app服务器收到它,将其发送到移动应用程序

    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. Mobile app does something with the data.移动应用程序对数据进行处理。

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

My problem is, I want to emit the 'message' event ONLY to the mobile app with the same authentication as the Web App where the Specific user is logged in.我的问题是,我只想将“消息”事件发送到与特定用户登录的 Web 应用程序具有相同身份验证的移动应用程序。

So if I log in TO THE WEB APP as: example@example.com / somepassword I want to emit the message event only to the mobile app in which the user is logged in with the same credentials.因此,如果我以以下身份登录到 WEB 应用程序:example@example.com / somepassword 我只想将消息事件发送到用户使用相同凭据登录的移动应用程序。

How do I do this?我该怎么做?

Thanks,谢谢,

You have to manage socket connection via session key or any other unique id.您必须通过会话密钥或任何其他唯一 ID 来管理套接字连接。 Basically, you have to manage the connection with unique id so you can find a particular connection when you need.基本上,您必须使用唯一 id 管理连接,以便您可以在需要时找到特定的连接。

Let's assume user with abc@gmail.com logged in a website and it's connected to a server.让我们假设用户abc@gmail.com登录了一个网站并且它连接到了服务器。 So server side you will get a new connection of abc@gamil.com user so we can store connection with name abc@gmail.com-web .因此,服务器端您将获得abc@gamil.com用户的新连接,因此我们可以存储名称为abc@gmail.com-web连接。 and same for mobile abc@gmail.com-mobile .和移动abc@gmail.com-mobile相同。

Now we have two connection of the same user with a different platform so when a user sends message from web we can forward this message to mobile using connection abc@gmail.com-mobile .现在我们有同一用户与不同平台的两个连接,因此当用户从web发送消息时,我们可以使用连接abc@gmail.com-mobile将此消息转发到mobile abc@gmail.com-mobile

More in-depth:更深入:

If you are using NodeJs as backend so you can use middleware to for JWT and verify which user is connected.如果您使用 NodeJs 作为后端,那么您可以使用中间件来处理 JWT 并验证连接了哪个用户。 Also open source library is available for this(i never tried) https://github.com/adcentury/socketio-jwt-auth也可以使用开源库(我从未尝试过) https://github.com/adseason/socketio-jwt-auth

In socket.io when a socket opens and connect to your server it remains until it disconnected so simply put, the socket object in connection callback of io object will remain same for any future send/receive action, so your solution is:在 socket.io 中,当套接字打开并连接到您的服务器时,它会一直保持到断开连接为止,所以简单地说, io对象的connection回调中的socket对象对于任何未来的发送/接收操作都将保持不变,因此您的解决方案是:

just replace this line:只需替换这一行:

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

with this:有了这个:

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

and your message event fire in the exact same user that logged in.并且您的message事件在登录的完全相同的用户中触发。

Hope i get your problem right and this answer will help you!希望我能解决您的问题,这个答案会对您有所帮助!

For those of you who are still wondering how to do it here is a code example:对于那些仍然想知道如何做到这一点的人,这里是一个代码示例:

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

Basically what we have done is created an auth middleware for our socket which will only connect the user if the authentication was passed.基本上我们所做的是为我们的套接字创建了一个 auth 中间件,它只会在通过身份验证的情况下连接用户。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM