You are correct, you can't prevent people from trying to connect to your socket.io server manually with a custom script using socket.io-client. Normally that's a reason for you to design the server in a way, that connected client sockets can't do any harm. Client sockets are usually on the receiving side.
But of course there is a best-practice on how to authenticate the connecting clients, and, if the authentication is failing, to prevent the connection. Checkout out the socket.io Documentation about client options. There is an auth field available :
Client
import { io } from "socket.io-client";
const socket = io({
auth: {
token: "abcd"
}
});
Server
io.on("connection", (socket) => {
console.log(socket.handshake.auth); // prints { token: "abcd" }
});
So once the user is logged in, use the JWT (Token) (assuming you having a JWT Authentication in place) and pass it during establishing the connection. Then validate the JWT on the server side.
client-certificate authentication
There is also a more advanced option for client authentication which uses certificates:
Client
const fs = require("fs");
const socket = require("socket.io-client")("https://example.com", {
ca: fs.readFileSync("./server-cert.pem"),
cert: fs.readFileSync("./client-cert.pem"),
key: fs.readFileSync("./client-key.pem"),
});
Server
const fs = require("fs");
const server = require("https").createServer({
cert: fs.readFileSync("./server-cert.pem"),
key: fs.readFileSync("./server-key.pem"),
requestCert: true,
ca: [
fs.readFileSync('client-cert.pem')
]
});
const io = require("socket.io")(server);