如何在nodejs应用程序中验证socket.io连接

tct7dpnv  于 2021-09-13  发布在  Java
关注(0)|答案(1)|浏览(458)

我正在开发一个聊天应用程序,其中套接字用于双向共享消息。
套接字目前工作正常,但我希望能够在用户能够访问套接字连接之前对其进行身份验证。我一直在尝试使用passport,但当我出现错误时,似乎有些事情我做得不对 No session found .

const createError = require("http-errors");
const express = require("express");
const { join } = require("path");
const logger = require("morgan");
const jwt = require("jsonwebtoken");
const cookieParser = require("cookie-parser");
const session = require("express-session");
const SequelizeStore = require("connect-session-sequelize")(session.Store);
const db = require("./db");
const { User } = require("./db/models");
const passport = require('passport');
// create store for sessions to persist in database
const sessionStore = new SequelizeStore({ db });
const http = require("http");
const db = require("../db");
const onlineUsers = require("../onlineUsers");
const passportSocketIo = require('passport.socketio');

const { json, urlencoded } = express;

const app = express();

app.use(logger("dev"));
app.use(json());
app.use(urlencoded({ extended: false }));
app.use(express.static(join(__dirname, "public")));
app.use(cookieParser());

app.use(session({
  genid:(req)=>{
    return req.cookies
  },
  secret:  process.env.SESSION_SECRET,
  resave: true,
  store: sessionStore,
  saveUninitialized: true,
}));

app.use(function (req, res, next) {

  const token = req.cookies["messenger-token"];

  if (token) {
    jwt.verify(token, process.env.SESSION_SECRET, (err, decoded) => {
      if (err) {
        return next();
      }
      User.findOne({
        where: { id: decoded.id },
      }).then((user) => {
        req.user = user;
        return next();
      });
    });
  } else {
    return next();
  }
});

app.use(passport.initialize());
app.use(passport.session());

const port = normalizePort(process.env.PORT || "3001");
app.set("port", port);

/**
 * Create HTTP server.
 */

const server = http.createServer(app);

/**
 * Listen on provided port, on all network interfaces, and sync database.
 */

const io = require("socket.io")(server, {
  cors: {
    origin: "http://localhost:3000",
    methods: ["GET", "POST", "PUT"],
    credentials: true
  }
});

io.use(
  passportSocketIo.authorize({
    cookieParser: cookieParser,
    key: 'messenger-token',
    secret: process.env.SESSION_SECRET,
    store: sessionStore,
    success: onAuthorizeSuccess,
    fail: onAuthorizeFail
  })
);

function onAuthorizeSuccess(data, accept) {
  console.log('successful connection to socket.io');

  accept(null, true);
}

function onAuthorizeFail(data, message, error, accept) {
  if (error) throw new Error(message);
  console.log('failed connection to socket.io:', message);
  accept(null, false);
}

io.on("connection", (socket) => {
  // console.log(`USER ${JSON.stringify(socket)}`);
  socket.on("go-online", (id) => {

    if (!onlineUsers.includes(id)) {
      onlineUsers.push(id);
    }
    // send the user who just went online to everyone else who is already online
    socket.broadcast.emit("add-online-user", id);
  });

  socket.on("new-message", (data) => {

    socket.broadcast.emit("new-message", {
      message: data.message,
      sender: data.sender,
    });
  });

  socket.on("read-message", (data) => {
    socket.broadcast.emit("read-message", data);
  });

  socket.on("read-messages", (data) => {
    socket.broadcast.emit("read-messages", data);
  });

  socket.on("logout", (id) => {
    if (onlineUsers.includes(id)) {
      userIndex = onlineUsers.indexOf(id);
      onlineUsers.splice(userIndex, 1);
      socket.broadcast.emit("remove-offline-user", id);
    }
  });
});

如何使用套接字对用户进行身份验证。除了使用passport外,您还可以自由建议其他方法。

pinkon5k

pinkon5k1#

我在github中发现了相同的错误,但尚未解决。
根据官方文档(请参阅“与express中间件的兼容性”一节),您可以在中使用express中间件 io.use 利用 wrap . 本节介绍如何将“快速会话”模块与socket.io一起使用。我想这种方式对你更好,因为你已经在使用它了。

相关问题