Passport.js cookie 不会持续存在,因此即使会话有通行证,登录验证也不起作用

Passport.js cookie not persist so login auth doesn't work even though session has the passport

我正在使用 passport.js 本地策略。 我在代理设置下测试它,本地主机。 在我准备部署之前一切正常。

我更改了 API 地址以包含 dotenv 并在服务器端设置了 CORS 设置。

  1. 尝试登录时,CORS 工作正常,OPTIONS 和 POST 获得 200 正常。客户端收到成功数据。保存在客户端的cookie。

  2. 但是,当身份验证检查进程在 Redux“isLoggedin”状态更新后立即运行时(useEffect),req.session 不会 没有护照对象。所以 deserializeUser 不会被调用。该会话包含除 Passport 之外的其他 cookie 信息。

  3. 这只在 Firefox 上(不是 Chrome):如果登录验证成功,页面将被重定向(它会在登录 redux 状态更改后立即检查),但由于它失败了,用户仍然停留在登录页面上。但是如果我再次尝试在同一页面上登录,cookie 就会开始显示护照对象。(换句话说,它从第二次尝试开始显示)。但它不会持续存在,因为 Redux 登录状态已在第一次登录尝试时更改为 true。(因此不会进行身份验证检查。)

客户:

Axios.post(
  `${process.env.REACT_APP_API_URI}/api/users/login`, 
   loginData,
   { withCredentials: true, }
).then((res) => res.data){
 //save isLoggedin to true in Redux 
}

// auth check logic starts right after changing isLoggedin. Axios Get to authenticateCheck

server.js

app.use(helmet());
// app.use(express.static('public'));
app.use("/uploads", express.static("uploads"));

// Passport configuration.
require("./utils/passport");

// connect to mongoDB
mongoose
  .connect(db.mongoURI, {
    useNewUrlParser: true,
    useUnifiedTopology: true,
    useCreateIndex: true,
    useFindAndModify: false,
  })
  .then(() => console.log("mongoDB is connected."))
  .catch((err) => console.log(err));

// CORS Middleware 
const corsOptions = {
  origin: "http://localhost:8000",
  optionsSuccessStatus: 200, // some legacy browsers (IE11, various SmartTVs) choke on 204
  credentials: true,
  methods: ["POST", "GET", "DELETE", "PUT", "PATCH", "OPTIONS"],
  allowedHeaders:
    "Origin, X-Requested-With, X-AUTHENTICATION, X-IP, Content-Type, Accept, x-access-token",
};

// app.use(cors(corsOptions));
app.options(/\.*/, cors(corsOptions), function (req, res) {
  return res.sendStatus(200);
});

app.all("*", cors(corsOptions), function (req, res, next) {
  next();
});

// to get json data
// support parsing of application/json type post data
app.use(express.json());

app.use((req, res, next) => {
  req.requestTime = new Date().toISOString();
  next();
});

//support parsing of application/x-www-form-urlencoded post data
app.use(express.urlencoded({ extended: true }));
app.use(cookieParser());

// db session store
const sessionStore = new MongoStore({
  mongoUrl: db.mongoURI,
  collection: "sessions",
});

// tell app to use cookie
app.use(
  session({
    secret: process.env.SESSION_SECRET_KEY,
    resave: false,
    saveUninitialized: false,
    store: sessionStore,
    cookie: {
      httpOnly: true,
      secure: false,
      sameSite:"none",
      maxAge: 24 * 60 * 60 * 1000, // 24 hours
      //keys: [process.env.COOKIE_ENCRYPTION_KEY]
    },
    name: "pm-user",
  })
);

// tell passport to make use of cookies to handle authentication
app.use(passport.initialize());
app.use(passport.session());

app.use(compression());

app.use(flash());

app.use((req, res, next) => {
  console.log("req.session:", req.session);
  // console.log('/////// req: ///////', req);
  console.log("////// req.user: ", req.user, " //////");
  next();
});

//---------------- END OF MIDDLEWARE ---------------------//

authController:

exports.authenticateCheck = (req, res, next) => {
  console.log("req.isAuthenticated():", req.isAuthenticated());
  if (req.isAuthenticated()) {
    return next();
  } else {
    return res.json({
      isAuth: false,
      error: true,
    });
  }
};

如果你能告诉我在哪里寻找修复它,那将是一个非常大的帮助。 谢谢

我终于找到了解决办法。 这是因为每次启动新请求而不是登录请求时都会更新会话。 解决方案是,我必须在前端的每个 Axios 选项中添加 { withCredentials: true }。