I am currently working on a socket.io-client/socket.io login system, the problem is when I start the server, a query is performed, retrieving the current data in the database, if a user registers they are not able to login until the server is restarted, if I use:
SELECT * FROM mytable ORDER BY id DESC LIMIT 1
Then only the user that just registered can login, and not users that are already registered, how can I resolve this issue?
I have it so when the username and passwords are submitted from the client to the server, the function containing the Mysql code is performed, logically I thought this would run the query again for each new connection, but it doesn't.
My Code:
Server:
console.log("Berdio - A Awesome socket server for everyone!")
console.log("Created with Love, by OzzieDev! Enjoy the awesomeness!")
var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);
function dosql(){
var mysql = require('mysql')
var connection = mysql.createConnection({
host : 'localhost',
user : 'root',
password : 'root',
database : 'Berd'
})
connection.query('SELECT * FROM Berd_Data', function(err, rows, fields, result){
if (err) throw err;
var usrname = rows[0].Username
var psword = rows[0].Password
global.usrname = usrname
global.psword = psword
});
}
io.on('connection', function(socket){
})
socket.on('user-name', function(data){
dosql()
socket.broadcast.emit('user-connected',data.u);
console.log(u,p)
var u = data.u
var p = data.p
console.log(u,p + " " + "emitted Data");
if (u === global.usrname && p === global.psword){
socket.emit('AuthGood')
}else{
socket.emit('AuthFail')
}
socket.on('msg',function(data){
var message = data.message
if (typeof message !== "undefined"){
socket.broadcast('newmsg',msg)
}
if(message === "quit"){
process.exit();
}
})
});
});
http.listen(3000, function(){
console.log('listening on *:3000');
});
Client:
var socket = require('socket.io-client')('http://127.0.0.1:3000');
socket.on('connect_error', function(){
console.log('Failed to establish a connection to the servers, or lost connection');
return process.exit();
});
var prompt = require("prompt-sync")()
console.log("Your Ip has been logged, but encrypted. Please see website for more info")
var news = "Add news: Will be from database. "
var username = prompt("Username>: ")
var password = prompt("Password>: ")
if (typeof username, password !== "undefined"){
socket.emit('request')
socket.emit('user-name', { u: username, p: password });
}
socket.on('AuthGood',function(socket){
console.log("Your details have been authenticated, hello again!")
var message = prompt("message>: ")
})
socket.on('AuthFail',function(socket){
console.log("Your details failed to authenticate, Wrong Pass/Username combination, quitting!")
return process.exit();
})
if (typeof message !== "undefined"){
socket.emit('msg',{m: message})
}
socket.on('user-connected',function(data){
var userconn = data.username
console.log(username +" " +"Has joined us!")
})
socket.on('newmsg',function(data){
var newmsg = data.msg
console.log("-----------------------------------")
console.log(username+">:" + " " +msg)
})
Using MySql query:
SELECT * FROM Berd_Data WHERE `Username` = ?', [u]
Fixed the issue.
Related
I'm trying to build a TCP server on node JS. The idea is to have multiple TCP clients connect and send / receive data(from server to client / client to server) and to have some sort of authentication (at least to enter a strong password) Also not sure if this approach is worth it. But, I've come up with something (most from online sources and docs) and crated below code.
Code runs and I can connect, but if I send data from client to server, the "password" check function fires up and each time I enter the correct password, a new (duplicate connection) is created. Seems like it keeps calling the same function on each input.
Desired behavior would be ; once client try's to connect, needs to provide the password and then start sending date. Also could someone give me a hint on how to send data back from server, or is it even possible. Or do I need to create a separate function for server.createConnection()
thanks in advance
UPDATE :I've changed the code a bit, but the main issue remains. this bit was supposed to check whether "clientAddress" exists and if so skip the auth part all together.
server.on('connection', (socket) => {
let clientAddress = `${socket.remoteAddress}:${socket.remotePort}`;
console.log(clientAddress)
if(sock.indexOf(clientAddress) !== -1){
console.log('devie found, opening communication')
newConnectionHandler(socket,clientAddress)
} else {
console.log('devie not found, need to authenticate')
userAuth(socket,clientAddress)
}
but as you can guess, it's not working :) if I manually specify the "clientAddress" it works , if I place "sock.push(clientAddress);" within the first block of code, it also works. No auth is asked. But when it's placed within
function userAuth(socket,clientAddress){
socket.write('password : ' )
socket.on('data', function (data) {
let pass = data.toString()
if (pass == password) {
sock.push(clientAddress);
console.log(sock)
newConnectionHandler(socket,clientAddress)
return;
} else {
//console.log(pass)
socket.write('Sorry, you cannot access the server \n')
console.log('acess denied for ' + socket.remoteAddress + ':' + socket.remotePort + '\n')
socket.write('connection closed')
socket.destroy()
}
})
}
code does run as expected and goes all the way till
function newConnectionHandler(socket,clientAddress){
//console.log(sock)
socket.write('Welcome \n')
socket.on('data', function(data1){
console.log("Client Sent: " + data1);
});
but as soon as I send a new message from the client, it goes back as if it was never authenticated and treats my input as the password and because it does not match with the actual password,it destroys the connection.
can someone please give me a hand...
const net = require('net');
const port = 3001;
const host = '192.168.0.165';
const server = net.createServer()
let sock = [];
let password = 123
//server.on('listening',createConnection);
server.on('connection', (socket) => {
let clientAddress = `${socket.remoteAddress}:${socket.remotePort}`;
console.log(clientAddress)
if(sock.indexOf(clientAddress) !== -1){
console.log('devie found, opening communication')
newConnectionHandler(socket,clientAddress)
} else {
console.log('devie not found, need to authenticate')
userAuth(socket,clientAddress)
}
server.on('error', errorHandler);
function errorHandler(err){
console.log(`Error occurred in ${clientAddress}: ${err.message}`);
}
function userAuth(socket,clientAddress){
socket.write('password : ' )
socket.on('data', function (data) {
let pass = data.toString()
if (pass == password) {
sock.push(clientAddress);
console.log(sock)
newConnectionHandler(socket,clientAddress)
return;
} else {
//console.log(pass)
socket.write('Sorry, you cannot access the server \n')
console.log('acess denied for ' + socket.remoteAddress + ':' + socket.remotePort + '\n')
socket.write('connection closed')
socket.destroy()
}
})
}
function newConnectionHandler(socket,clientAddress){
//console.log(sock)
socket.write('Welcome \n')
socket.on('data', function(data1){
console.log("Client Sent: " + data1);
});
socket.once('close', (data) => {
let index = sock.findIndex((o) => {
return o.remoteAddress === socket.remoteAddress && o.remotePort === socket.remotePort;
})
if (index !== -1) sock.splice(index, 1);
sock.forEach((sock) => {
socket.write(`${clientAddress} disconnected\n`);
});
console.log(`connection closed: ${clientAddress}`);
});
}
/* function createConnection(){
// Start a connection to the server
var socket = server.on('connect',function(){
// Send the initial message once connected
socket.write({question: "Hello, world?"});
});
// Whenever the server sends us an object...
socket.on('data', function(data){
// Output the answer property of the server's message to the console
console.log("Server's answer: " + data.answer);
});
} */
})
server.listen(port, host, () => {
console.log('TCP Server is running on port ' + port + '.');
});
so it appears as the only bit of code that was causing the authentication loop was the
function userAuth(socket,clientAddress){
socket.write('password : ' )
**socket.on('data', function (data) {**
let pass = data.toString()
after changing "on" with "once" it is now functioning properly. I tested with two TCP clients, both connected and was asked to enter a password. They can both actively send messages to the server and both disconnected properly in the end.
this is the code if anyone finds any use for it :) the connection it's self is still unencrypted so not good for sending/receiving sensitive data.
const net = require('net');
const port = 3001;
const host = '192.168.0.165';
const server = net.createServer()
let sock = [];
let password = 123
//server.on('listening',createConnection);
server.on('connection', (socket) => {
let clientAddress = `${socket.remoteAddress}:${socket.remotePort}`;
console.log(clientAddress)
if(sock.indexOf(clientAddress) !== -1){
console.log('devie found, opening communication')
newConnectionHandler(socket,clientAddress)
} else {
console.log('devie not found, need to authenticate')
userAuth(socket,clientAddress)
}
})
server.on('error', errorHandler);
function errorHandler(err){
console.log(`Error occurred in ${clientAddress}: ${err.message}`);
}
function userAuth(socket,clientAddress){
socket.write('password : ' )
socket.once('data', function (data) {
let pass = data.toString()
if (pass == password) {
sock.push(clientAddress);
console.log(sock)
newConnectionHandler(socket,clientAddress)
return;
} else {
//console.log(pass)
socket.write('Sorry, you cannot access the server \n')
console.log('acess denied for ' + socket.remoteAddress + ':' + socket.remotePort + '\n')
socket.write('connection closed')
socket.destroy()
}
})
}
function newConnectionHandler(socket,clientAddress){
//console.log(sock)
socket.write('Welcome \n')
socket.on('data', function(data1){
console.log("Client Sent: " + data1);
});
socket.on('close', function(data) {
let index = sock.findIndex(function(o) {
return o.remoteAddress === sock.remoteAddress && o.remotePort === sock.remotePort;
})
if (index !== -1) sock.splice(index, 1);
console.log('CLOSED: ' + socket.remoteAddress + ' ' + socket.remotePort);
});
}
/* function createConnection(){
// Start a connection to the server
var socket = server.on('connect',function(){
// Send the initial message once connected
socket.write({question: "Hello, world?"});
});
// Whenever the server sends us an object...
socket.on('data', function(data){
// Output the answer property of the server's message to the console
console.log("Server's answer: " + data.answer);
});
} */
server.listen(port, host, () => {
console.log('TCP Server is running on port ' + port + '.');
});
I'm building a simple chat using this guide.
When someone login their name is appended to the list of online users. However, each user should not see his/her own name in the list, only the name of the other users. Any suggestions to what I should add/change in my code to fix this?
client-side:
socket.on("update-people", function(data, id){
$("#people").empty();
$.each(data.people, function(a, obj, id) {
$('#people').append("<li class=\"people-item\"><span class="+obj.id+">" + obj.name + "</span></li>");
});
});
socket.on("update-people-withSelf", function(people){
$('#people').append("<li class=\"people-item\"><span class="+people.id+">" + people.name + "</span></li>");
});
server-side:
// Setting up the server
var express = require('express');
var app = express();
var path = require('path');
var server = require('http').createServer(app);
var socket = require("socket.io").listen(server);
var Room = require('./room.js');
var Conversation = require('./conversation.js');
var _ = require('underscore')._;
var uuid = require ('uuid');
server.listen(process.env.PORT || 3000);
console.log('Server is running...');
socket.set("log level", 1);
var people = {};
var rooms = {};
var conversations = {};
var clients = [];
var chatHistory = {};
Array.prototype.contains = function(k, callback) {
var self = this;
return (function check(i) {
if (i >= self.length) {
return callback(false);
}
if (self[i] === k) {
return callback(true);
}
return process.nextTick(check.bind(null, i+1));
}(0));
};
// Gets the html file
app.get('/', function(req, res){
res.sendFile(__dirname + '/index.html');
})
// Gets the css file
app.use(express.static(path.join(__dirname, 'public')));
// When connecting
socket.on("connection", function(client) {
client.on("join", function(name){
client.emit("update-people", {people: people});
sizePeople = _.size(people);
socket.sockets.emit("update-peopleCount", {people: people, count: sizePeople});
var ownerRoomID = inRoomID = null;
roomID = null;
conversationID = null; // This line probably has to go, since users should be able to create several conversations.
people[client.id] = {"name" : name, "owns" : ownerRoomID, "inroom" : inRoomID, "id" : client.id, "room" : roomID, "conversation" : conversationID};
var id = uuid.v4();
//sizePeople = _.size(people);
sizeRooms = _.size(rooms);
sizeConversations = _.size(conversations);
//socket.sockets.emit("update-peopleCount", {people: people, count: sizePeople});
//socket.sockets.emit("update-people", {people: people});
socket.sockets.emit("roomList", {rooms: rooms, count: sizeRooms});
socket.sockets.emit("update-conversations", {conversations: conversations, count: sizeConversations});
client.emit("updateToSelf", "You have connected to the server. Start conversation or create/join room to chat");
client.broadcast.emit('updateToOthers', name + " is online.");
clients.push(client); //populates the clients array with the client object
console.log("Someone joined the chat", people[client.id].id);
//client.broadcast.emit("sendingOwnName", people[client.id].id);
client.broadcast.emit("update-people-withSelf", people[client.id]);
});
If those people have some id assigned to them, then you can have
condition in your loop to not append user him/herself.
if(obj.id !== currentUser.id) { $'#people').append(... }
Of course you can also use user name or some other info.
I found a solution to my problem. I have updated my question with the correct code.
Basically what was needed was an update of users BEFORE the new user is given an id, name ect. Afterwards, that new user broadcast his/her name to the other users.
I have a chat application where I have to handle online users.
How can i send user name in:
var myIoSocket = io.connect();
So i can make a list at the backend.
currently i am doing like this.
Socket.on("connect",function(){
Notification.primary('Connected');
Socket.emit('iamonline',{
username: $rootScope.username
});
});
Backend :
var onlineUsers = {};
io.sockets.on('connection', function(socket){
socket.on('iamonline',function (data) {
console.log(data.username," connected.")
onlineUsers[data.username] = socket;
Users[data.username] = socket;
currentUser = data.username;
console.log(socket)
io.sockets.emit("liveusers",Object.keys(onlineUsers));
});
socket.on('disconnect', function(){
delete onlineUsers[currentUser];
console.log(currentUser," disconnected.");
io.sockets.emit("liveusers",Object.keys(onlineUsers));
});
});
I had same issue for a different project and found out the best way to do it with query and get value on handshake.
server.js
io.on('connection' , function(socket){
if(typeof socket.handshake.name!="undefined"){
user = {
name : socket.handshake.query.name,
id : socket.handshake.query.id,
email : socket.handshake.query.email,
}
}
});
on client side,
if(typeof io != "undefined"){
var visitor = io.connect('ws://127.0.0.1:8000' , {
'query': $.param({token: '<?=Session::$instance->session['id']?>'}) + '&name=<?=Session::get("username")?>&id=<?=Session::get("ID")?>&email=<?=Sesion::get("Email")?>'
});
}
The code is only displaying the last record from the database. What do I do to get it to display all the records from the database. I'm trying this by using nodeJS. Thank you
var express = require('express');
var mysql = require('mysql');
var app = express();
var data;
var connection = mysql.createConnection({
host : 'localhost',
user : 'root',
password : '',
database : 'music'
});
connection.connect();
connection.query('SELECT * FROM artist', function(err, rows, fields) {
if(err) throw err;
data = JSON.stringify(rows);
for(var i=0;i<rows.length;i++)
data = rows[i].artist_name + " "+rows[i].artist_id;
});
connection.end();
app.get("/artists", function(req,res){
res.send(data);
})
var myServer = app.listen(3000, function(){
console.log("Server listening on port 3000");
})
You are assigning your data value to each row in the for loop; that is, every iteration of the loop, you replace the value. Instead of using the assignment operator (=) use a contaminator (+=):
var data = "";
var rowDelimiter = "<br>"; // Or whatever you want
And then:
data += rows[i].artist_name + " "+rows[i].artist_id + rowDelimiter;
I am trying to save session data inside a handshake object from io.set('authorization')
var io = sio.listen(server);
io.set('authorization', function (handshake, callback) {
if(handshake.headers.cookie) {
var cookies = cookie.parse(handshake.headers.cookie);
var sid = cookieParser.signedCookie(cookies['xygaming'], secrets.sessionSecret);
sessionStore.load(sid, function(err, session) {
if(err || !session) {
return callback('Error retrieving session!', false);
}
// this is not storing the data into the handshake object
handshake.balloons = {
user: session.passport.user,
room: /\/(?:([^\/]+?))\/?$/g.exec(handshake.headers.referer)[1]
};
return callback(null, true);
});
} else {
return callback('No cookie transmitted.', false);
}
});
I have an adapter for pub sub
io.adapter(redisIo({
host: 'localhost',
port: 6379,
pubClient: pub, // just redis.createClient()
subClient: sub // just redis.createClient()
}));
Then I want to access the handshake data inside the io.sockets.on('connection') but its not there? Any idea why its not passing? In the original repo it works on express 3x, but since I upgraded to 4x and made some modifications of my own it does not pass through?
io.sockets.on('connection', function (socket) {
console.log(socket.handshake);
// I want to pass the handshake data here, but its undefined??
var hs = socket.handshake
, nickname = hs.balloons.user.username
, provider = hs.balloons.user.provider
, userKey = provider + ":" + nickname
, room_id = hs.balloons.room
, now = new Date()
// Chat Log handler
, chatlogFileName = './chats/' + room_id + (now.getFullYear()) + (now.getMonth() + 1) + (now.getDate()) + ".txt"
// , chatlogWriteStream = fs.createWriteStream(chatlogFileName, {'flags': 'a'});
socket.join(room_id);
});