0

**I've seen a few posts regarding this question, or in the style of this question, but they were asked quite a long time ago, and I wanted to get an updated answer, which might help others as well

I've been working on a simple website (for learning) using PHP, with registration and login system. Now there are pages that are accessible only to logged-in users. In PHP I simply start a session, giving the users their unique session_id whenever they log in, and if the page is meant to be viewed only by logged-in users, I simply check if the session is set, and also get the session content, which will be used to fetch the user details from the database (name, birthday, etc)

Now I want to add real time chat capability, using socket.io with Node.js. So I need to allow access only to logged in users, and get their session id so that I can get their name from the database to display. This is the basic working chat so far, which is working to anyone who lands on localhost:3000: (contains 2 files: index.html, and index.js)

Edit:

this is what I use in PHP to log in users:

session_start();
$_SESSION['username'] = $username;

And check if they're logged in:

if (!isset($_SESSION['username'])) { //do stuff

And I want the chat content to be saved (like Facebook or WhatsApp chats), so I need the session to be accessible by nodeJS to insert the chat content into the database, and also to fetch previous content from the database, no? Or I can do it only via PHP?

----End Edit----

index.js:

var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);

app.get('/', function(req, res){
  res.sendFile(__dirname + '/index.html');
});

io.on('connection', function(socket){
  console.log('a user connected');
    socket.on('chat message', function(msg){
    io.emit('chat message', msg);
    });
  socket.on('disconnect', function(){
    console.log('user disconnected');   
  });
});

http.listen(3000, function(){
  console.log('listening on *:3000');
});

index.html:

<!doctype html>
<html>
  <head>    
    <script src="socket.io/socket.io.js"></script>
    <script
        src="https://code.jquery.com/jquery-3.3.1.min.js"
        integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8="
        crossorigin="anonymous"></script>
    <script>
    $(function () {
        var socket = io();
        $('form').submit(function(){
        socket.emit('chat message', $('#m').val());
        $('#m').val('');
        return false;
    });
    socket.on('chat message', function(msg){
        $('#messages').append($('<li>').text(msg));
    });
  });
</script>
    
    <title>Socket.IO chat</title>
    <style>
      * { margin: 0; padding: 0; box-sizing: border-box; }
      body { font: 13px Helvetica, Arial; }
      form { background: #000; padding: 3px; position: fixed; bottom: 0; width: 100%; }
      form input { border: 0; padding: 10px; width: 90%; margin-right: .5%; }
      form button { width: 9%; background: rgb(130, 224, 255); border: none; padding: 10px; }
      #messages { list-style-type: none; margin: 0; padding: 0; }
      #messages li { padding: 5px 10px; }
      #messages li:nth-child(odd) { background: #eee; }
    </style>
    
  </head>
  <body>

    <ul id="messages"></ul>
    <form action="">
      <input id="m" autocomplete="off" /><button>Send</button>
    </form>
  </body>
</html>

What do I need to do?

Thanks

Community
  • 1
  • 1
  • 1
    What does "logged in users" mean? Why don't you check for that condition and wrap the calls to initialize the chat in that condition? – Nico Haase May 02 '18 at 14:48
  • it means that session has started with their unique session taken from the database when they provide their username and password: session_start(); $_SESSION['username'] = $username; But I want the chat to be saved, so I need the session details in the JS code, to add the messages to the MySQL database, no? –  May 02 '18 at 14:50

1 Answers1

0

You could send the username with the chatmessage. So for example your chat message contains "Hello world" and the user "John Doe" sent it. Then you could send an object like this instead of only the message:

{ "name": "John Doe", "message": "Hello World" }

to your chat application.

On the other end you decode this JSON object, and simply display the name and the message.

In your case this would mean replacing the following:

socket.emit('chat message', $('#m').val());

with

socket.emit('chat message', {name: "John Doe", message: $('#m').val()});

And

$('#messages').append($('<li>').text(msg));

With

$('#messages').append($('<li>').text(msg.name + ": " + msg.message));
Teun
  • 165
  • 1
  • 7
  • Thank you, btw I edited the post (under **edit). Edit about how to enable the chat to only logged in users. Does that mean I can simply leave the PHP condition "if (!isset($_SESSION['username']))" above the chat file (index.html)? –  May 02 '18 at 14:55
  • 1
    That would work, although it isn't completely secure. Anyone that knows about your NodeJS server can still send and receive messages from your chat. Regarding your edit: You can save messages within Javascript, so that you don't need PHP. LocalStorage seems like the right API for this: https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage – Teun May 02 '18 at 14:58
  • I see, then what would your approach be, in order to verify that a user is logged in via the node? so that even someone is knows about the server won't be able to chat unless he is that specific user? I will somehow need to pass the session to index.js for verification, right? Or there is a different approach –  May 02 '18 at 15:00
  • 1
    That's more complex still, you would need some sort of token on the client side (Javascript) end which you can associate the user with. It might be a little complex compared to what you've done. It's also something you can't simply explain in an edit like this, this thread seems to explain it: https://stackoverflow.com/questions/29121112/how-to-implement-token-based-authentication-securely-for-accessing-the-website – Teun May 02 '18 at 15:03
  • So if I wanted to add token-based authentication (to the current PHP based website), it means that a new token will be created every time user lands on "logged-in only" page (just an example) –  May 02 '18 at 15:06
  • 1
    @pileup not necessarily, look into jwt – JimL May 02 '18 at 15:11
  • I will look right away, but I have a few questions: (1) Will JWT replace the current Session based login system? (2) How hard will it be to add JWT system to a beginner? (3) Is JWT going to help me with checking if user is logged in, in the nodeJS file? –  May 02 '18 at 15:15
  • (1) It could, but that isn't needed (2) JWT as a concept isn't difficult, getting an implementation working is more difficult. (3) JWT can help you check if the user is logged in – Teun May 03 '18 at 08:02