我有一个奇怪的问题。我发现问题在哪里,但我不知道如何解决它。我使用cookie-parser
,express-mysql-session
,express-session
,connect-flash
,passport
等在我的项目中。为了在mySQL database
中存储会话,我使用express-mysql-session
模块。但这个模块使connect-flash
出现问题。这是我配置第一个中间件的地方:
const setFirstMiddleWares = (server: Express) => {
if (devMode) server.use(morgan("dev"));
server.use(bodyParser.urlencoded({ extended: false }));
server.use(cookieParser());
server.use(
expressSession({
secret: "secret",
saveUninitialized: false,
resave: false,
store: MySQLSessionStore, //the problem is exactly this line
})
);
server.use(flash());
server.use(passport.initialize());
server.use(passport.session());
server.use(setRenderConfig);
};
express-mysql-session
给connect-flash
造成的问题是,当我在中间件中设置一个消息connect-flash
,然后我将用户重定向到例如登录页面时,第一次没有消息显示在视图中。但当我刷新登录页面时,消息将显示!但当我删除express-session
配置对象的存储属性时,一切都会很好,用户重定向到登录页面后,flash消息将立即显示在登录视图中,登录页面不需要刷新来显示错误或成功消息!这对于flash-connect
来说确实是一个奇怪的行为。您可以看到我的代码的重要部分:DB.ts:
mport mysql from "mysql2/promise";
import MySQLStoreSessionsStore from "express-mysql-session";
import * as expressSession from "express-session";
const dbConfig = {
host: process.env.DBHOST,
user: process.env.DBUSER,
password: process.env.DBPASSWORD,
port: Number(process.env.DBPORT),
database: process.env.DATABASENAME,
};
const connection = mysql.createPool(dbConfig);
const MySQLSessionStoreClass = MySQLStoreSessionsStore(expressSession);
const MySQLSessionStore = new MySQLSessionStoreClass({}, connection);
export { connection as mysql, MySQLSessionStore };
Users.ts:
import { NextFunction, Request, Response } from "express";
import passport from "passport";
import { signUpUser } from "../models/Users";
const signUpUserController = async (
req: Request,
res: Response,
next: NextFunction
) => {
try {
await signUpUser(req.body);
req.flash("sign-in-successes", [
"your account has been created successfully! please login to your account.",
]);
res.redirect("/login");
} catch (errors) {
if (Array.isArray(errors)) {
req.flash("sign-up-errors", <string[]>errors);
res.redirect("/sign-up");
} else next({ error: errors, code: "500" });
}
};
const signInUserController = (
req: Request,
res: Response,
next: NextFunction
) => {
passport.authenticate("local", {
failureRedirect: "/login",
failureFlash: true,
})(req, res, next);
};
const remmemberUserController = (req: Request, res: Response) => {
console.log("line 5:", req.body);
if (req.body["remmember-user"]) {
req.session.cookie.originalMaxAge = 253402300000000;
} else {
req.session.cookie.expires = undefined;
}
res.redirect("/account/dashboard");
};
const logOutController = (req: Request, res: Response, next: NextFunction) => {
req.logOut({ keepSessionInfo: false }, (err) => {
console.log(err);
req.flash("sign-in-successes", ["logged out successfuly!"]);
res.redirect("/login");
});
};
export {
signUpUserController,
signInUserController,
logOutController,
remmemberUserController,
};
passport.ts:
import passport from "passport";
import localStrategy from "passport-local";
import bcrypt from "bcrypt";
import { getUsersInfos } from "../models/Users";
passport.use(
new localStrategy.Strategy(
{
usernameField: "user-email-signin",
passwordField: "user-password-signin",
},
async (email, password, done) => {
try {
const user: any = await getUsersInfos(email);
if (Array.isArray(user)) {
const length: 2 | number = user.length;
if (length === 0) {
return done(null, false, {
message: "user with your entered email not found!",
});
}
const isMatch = await bcrypt.compare(password, user[0].password);
if (isMatch) {
return done(null, user);
} else {
return done(null, false, {
message: "email or password are incorrect!",
});
}
} else {
return done(null, false, {
message: "something went wrong. please try again!",
});
}
} catch (error) {
console.log(error);
}
}
)
);
passport.serializeUser((user, done) => {
done(null, user);
});
passport.deserializeUser(async (user, done) => {
if (Array.isArray(user)) {
done(null, user[0].id);
}
});
LoginController.ts:
import { Request } from "express";
import { NewExpressResponse } from "../types/Types";
const loginController = (req: Request, res: NewExpressResponse) => {
res.render("login", {
title: `login`,
scripts: [...res.locals.scripts, "/js/LoginScripts.js"],
successes: req.flash("sign-in-successes"),
error: req.flash("error"),
});
};
export { loginController };
我在谷歌搜索了很多这个问题,但我发现的唯一一件事是,我应该在我的中间件中使用req.session.save(() => { res.redirect("/login");})
来显示用户重定向到路由后立即在视图中的flash消息.但这种方式有一些问题:
1.我应该使用这个代码为每一个重定向,如果我想设置和使用的flash消息在重定向路由,我其实不喜欢这个。
1.我不能在signInUserController
中做这样的事情,因为passport自己在flash中设置错误。
那么,当我使用express-mysql-session
时,你有什么想法来修复connect-flash
的这种奇怪行为吗?谢谢帮助:)
1条答案
按热度按时间rt4zxlrg1#
我发现这是
connect-flash
中的一个问题(实际上不是问题,是一个可以添加的特性)。它本身不保存会话。正因为如此,我创建了这个包的异步版本,其中包含更多特性。您可以使用promise基函数或回调基函数来保存和获取您的flash消息。因此您可以使用async-connect-flash
而不是connect-flash
。我希望您喜欢它:)