mustpax / node-express-passport-socketio

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Choose your own adventure: Authentication with Socket.io

Which one describes you best?

Authentication with socket.io with Express and Passport

Why is this blip important to a robust project?

Express applications that use Passport for user logins can access the currently logged in user via req.user. In order to get access to req.user inside socket.io you need to create a socket.io middleware function via io.use().

Code

From passport/app.js

io.use(function(socket, next) {
  const cookie = socket.handshake.headers.cookie;
  const req = {
    headers: {
      cookie
    }
  };
  session(req, {}, function(err) {
    if (err) {
      console.error("Error running session middleware", err);
    }
    let serializedUser = req.session[passport._key].user;
    if (!serializedUser) {
      next();
      return;
    }
    passport.deserializeUser(serializedUser, function(err, user) {
      if (err) {
        console.error("Error desrializing user", err);
      }
      socket.user = user;
      next();
    });
  });
});

Other benefits

  1. Once a user is logged in, their information is securely accessible on the server in both Express and socket.io.
  2. You only need to implement login logic once.
  3. Passport logins via OAuth login providers (such as Facebook) are supported.
  4. You can use any Express session middleware such as express-session or cookie-session.

Authentication with socket.io with no Passport

Why is this blip important to a robust project?

We use JSON Web Tokens and localStorage to implement peristent user authentication (i.e. user login) for applications that use socket.io. We accomplish this goal by defining two socket.io message types: login and auth. login is triggered when a user logs in from a new browser. auth is triggered when a logged in user returns to our site.

Code

From json-web-token/app.js

io.on("connection", function(socket) {
  socket.user = null;

  socket.on("login", function(data) {
    const { username, password } = data;
    // INSECURE CODE START
    if (username === "user" && password === "pass") {
      // INSECURE CODE END
      const token = jwt.sign({ username }, SECRET, {
        expiresIn: "1 week",
        algorithm: JWT_ALGO
      });
      socket.user = { username };
      socket.emit("login-success", { token, username });
    } else {
      socket.emit("login-fail", { error: "Bad username or password" });
    }
  });

  socket.on("auth", function(data) {
    const { token } = data;
    try {
      const verifiedToken = jwt.decode(token, SECRET, {
        algorithms: [JWT_ALGO]
      });
      socket.user = { username: verifiedToken.username };
      socket.emit("auth-success", { username: verifiedToken.username });
    } catch (e) {
      socket.emit("auth-fail", { error: e.message });
    }
  });
});

Other benefits

  1. Once a user is logged in their information is securely accesible via socket.user.
  2. Session tokens are generated and validated securely via (JSON Web Tokens aka JWT)(https://github.com/auth0/node-jsonwebtoken)
  3. User login session length is securely controlled via JWT.
  4. Session tokens are stored using localStorage on the client. Does not use cookies.

About

License:MIT License


Languages

Language:JavaScript 72.5%Language:HTML 27.5%