NodeJS 无法注销passport js并删除cookie

2q5ifsrm  于 2023-06-29  发布在  Node.js
关注(0)|答案(1)|浏览(104)

我有一个示例节点应用程序,我试图在其中使用passport js注册登录和注销用户。我可以成功地登录和注册用户,但当我试图在我的终端注销用户时,我只得到我的反序列化函数的console.log,它不会影响我浏览器中的cookie,也不会注销用户,因为我可以在调用注销函数后检索req.user。下面是我的passport和express设置、序列化和反序列化函数,以及我的注销、注册和登录函数:

//middleware
app.use(session({
    secret: "secret",
    resave: true,
    saveUninitialized: true,
    cookie: {maxAge:60*60*1000}//1hour
}));
app.use(express.urlencoded({
    extended: false
 }));
 app.use(express.json());
app.use(cors({
    origin: "http://localhost:3000",
    credentials: true,
}));
app.use(cookieParser("secret"));
app.use(passport.initialize());
app.use(passport.session());

passport.serializeUser((user, cb) => {
    console.log("serializing user");
    cb(null, user.id);
});
passport.deserializeUser((id, cb) => {
    User.findById(id).then((err, user) => {
        if(err) throw err;
        console.log("id: " + id);
        console.log("userid: " + user);
        const userInformation = {
            username: user.email,
        };
        cb(err, user);
    }).catch((err) => {console.error(err)});
});

passport.use(
    new localStrategy(async (username, password, done) => {
        try{
            const user = await User.findOne({username: username});
            if(!user) {
                console.log("no user");
                return done(null, false);
            }
            bcrypt.compare(password, user.password, (err, result) => {
                if(err) throw err;
                if(result === true) {
                    return done(null, user);
                } else {
                    return done(null, false);
                }
            });
        } catch(err){
            console.log("err inside localStrategy: " + err);
            throw err;

        }
    }) 
);

app.post("/login", (req, res) => {
    console.log("inside login");

    passport.authenticate("local", (err, user, info) => {
        console.log("inside authenticate, user: " + user);
        if(err) {
            console.log("err: " + err);
            throw err;
        }
        if(!user) {
            console.log("No user");
            res.status(400);
            res.send("No user exists");
        }
        else {
            console.log("inside else");
            req.logIn(user, (err) => {
                if(err) throw err;
                console.log("req.user: " + req.user);
                console.log("successfully authenticated");
                res.status(200).json({message: "successfully authenticated here"});
            });
        }
    })(req, res);
});

app.post("/register", async (req, res) => {
    
    try {
        console.log("username: " + req.body.username);
        const existingUser = await User.findOne({username: req.body.username});
        if(existingUser) {
            console.log("duplicate user");
            return res.status(400).json({message: "User already exists"});
        }
        console.log("password to be hashed: " + req.body.password);
        //hash password
        const newUser = new User({
            username: req.body.username,
            password: req.body.password
        });
        bcrypt.genSalt(10, (err,salt)=>
            bcrypt.hash(newUser.password, salt,
                (err, hash) =>{
                    if(err) throw err;
                    newUser.password = hash;
                    newUser.save()
                    .then((value)=> {
                        console.log("value: " + value);
                        console.log("registered: " + newUser.username);
                        return res.status(200).json({message: "User successfully registered"});
                    })
                    .catch(err => console.log(err));
                }
            )
        );
    }
    catch (err) {
        console.log("error registering: " + err);
        res.status(500).json({message: "Internal srever error"});
    }
});

app.get("/logout", function(req, res){
    req.logout();
    req.session.destroy(function(err){
        if(err){
            console.log("error: " + err);
            res.status(500).json({message: "Error destroying session"});
        } else {
            console.log("destroying session");
            res.clearCookie('mcookie');
            res.status(200).json({message: "Logged out successfully"});
        }
    });
});
uinbv5nw

uinbv5nw1#

问题出在passport.deserializeUser函数中。
OP在他们的描述中说,它记录deserializeUser函数,没有任何变化。因此,程序的控制流似乎永远不会超出deserializeUser函数。如果我们查看浏览器的网络控制台,它会记录500 Internal Server error
此外,OP还说,req.logout函数没有回调,永远不会在其端给出错误。而且它应该会失败,因为这个函数,截至目前(版本0.6.0),requires a callback。这也引起了一些人的注意。

解决方案

阅读代码,似乎错误出现在findById函数的then部分:

passport.deserializeUser((id, cb) => {
    User.findById(id).then((err, user) => { //<== here
        if(err) throw err;
        console.log("id: " + id);
        console.log("userid: " + user);
        const userInformation = {
            username: user.email,
        };
        cb(err, user);
    }).catch((err) => {console.error(err)});

看来你已经交换了那些论点。所以解决方案就是简单地交换这些参数。

passport.deserializeUser((id, cb) => {
    User.findById(id).then((user,err) => { //now correct
        if(err) throw err;
        console.log("id: " + id);
        console.log("userid: " + user);
        const userInformation = {
            username: user.email,
        };
        cb(err, user);
    }).catch((err) => {console.error(err)});
});

所以现在程序应该运行良好,它应该调用你的req.logout函数。这应该会给予错误,因为你没有向函数传递回调。
希望这有帮助!问你是否需要澄清。

相关问题