简体   繁体   中英

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. The web application has a register/login system integrated with JWT in the headers.

What I want to do is this: Let's assume the user is logged in on the web app.

  1. The user sends a socket from the web app

     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.

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.

How do I do this?

Thanks,

You have to manage socket connection via session key or any other unique id. Basically, you have to manage the connection with unique id so you can find a particular connection when you need.

Let's assume user with abc@gmail.com logged in a website and it's connected to a server. 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 . and same for 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 .

More in-depth:

If you are using NodeJs as backend so you can use middleware to for JWT and verify which user is connected. Also open source library is available for this(i never tried) https://github.com/adcentury/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:

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.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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