护照身份验证不适用于 nodejs 和 mysql

Posted

技术标签:

【中文标题】护照身份验证不适用于 nodejs 和 mysql【英文标题】:passport authentication is not working with nodejs and mysql 【发布时间】:2021-06-14 09:39:48 【问题描述】:

嗨,我正在尝试使用带有 nodejs 和 mysql 的护照身份验证来验证我的登录页面,但没有任何效果,在我的浏览器登录页面中,我只收到一条警报消息“缺少凭据”,我什至没有包含在我的 passport.js 文件中,我尝试了很多教程,但没有一个有用,我希望有人能帮助我,并解释我的代码哪里出错。

主索引文件

const express = require("express");
const path = require("path");
const db = require("./config/db_config.js");
const session = require("express-session");
const flash = require("connect-flash");
const passport = require("passport");

const app = express();

// passport config
require("./config/passport")(passport);

//body parser
app.use(express.json());
app.use(express.urlencoded( extended: false ));

app.use(express.static(path.join(__dirname, "public")));

// handlebars
app.set("view engine", "hbs");

// // express session
app.use(
    session(
        secret: "geeksforgeeks",
        saveUninitialized: true,
        resave: true,
    )
);

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

app.use(flash());

// global  varible
app.use((req, res, next) => 
    res.locals.success_msg = req.flash("success_msg");
    res.locals.error_msg = req.flash("error_msg");
    res.locals.error = req.flash("error");
    next();
);

// routes for registration and login page
app.use("/", require("./routes/first"));
app.use("/post", require("./routes/post"));

const MY_PORT = process.env.PORT || 5000;

app.listen(MY_PORT, () => console.log(`server running on port $MY_PORT`));

护照验证文件

const LocalStrategy = require("passport-local").Strategy;
const connection = require("./db_config");
const bcrypt = require("bcryptjs");

module.exports = function (passport) 
    passport.use(
        "local",
        new LocalStrategy(
            
                usernameField: "email",
                passwordField: "password",
                passReqToCallback: true,
            ,
            (req, email, password, done) => 
                console.log(req.body);

                if (!email || !password) 
                    return done(
                        null,
                        false,
                        req.flash("message", "All fields are required.")
                    );
                
                //  check if email is registered or not
                connection.query(
                    "SELECT * FROM users WHERE email =?",
                    [email],
                    (err, rows) => 
                        if (err) return done(err);
                        if (!rows.length)
                            return done(
                                null,
                                false,
                                req.flash("message", "email is not registered")
                            );

                        //  if the user is found but the password is wrong
                        if (!bcrypt.compareSync(password, rows[0].password))
                            return done(
                                null,
                                false,
                                req.flash("message", "oops..! wrong password")
                            );

                        // if user is found return successful user
                        return done(null, rows[0]);
                    
                );
            
        )
    );

    // serialize user for the session
    passport.serializeUser((user, done) => 
        done(null, user.id);
    );

    //used to deserialize the user
    passport.deserializeUser((id, done) => 
        connection.query("SELECT * FROM users WHERE id=?", [id], (err, rows) => 
            console.log(rows);
            console.log(err);
            done(err, rows[0]);
        );
    );
;

路由文件

const express = require("express");
const router = express.Router();
const db = require("../config/db_config.js");
const bcrypt = require("bcryptjs");
const passport = require("passport");

//  registration
router.get("/register", (req, res) => 
    res.render("register");
);

// inserting values into database
router.post("/register", (req, res) => 
    const  firstname, lastname, email, password, passwordconfirm  = req.body;

    // validating  email already exist or not from database

    let sql = "SELECT email FROM users WHERE email=?";

    db.query(sql, [email], async (err, results) => 
        if (err) throw err;

        if (!firstname || !lastname || !email || !password || !passwordconfirm) 
            return res.status(400).render("register", 
                message: "please fill all the details",
            );
         else if (password !== passwordconfirm) 
            return res.status(400).render("register", 
                message: "passwords do not match",
            );
         else if (results.length > 0) 
            return res.status(400).render("register", 
                message: "email already exist",
            );
        
        console.log(results);
        // inserting form data into database
        let hashed = await bcrypt.hash(password, 8);
        console.log(hashed);
        const user = 
            first_name: firstname,
            last_name: lastname,
            email: email,
            password: hashed,
        ;
        db.query("INSERT INTO users SET ?", user, (err, result) => 
            if (err) 
                throw err;
             else 
                console.log(result);
                req.flash("success_msg", "you registered successfully");
                res.redirect("/post/login");
            
        );
    );
);

//  login
router.get("/login", (req, res) => 
    res.render("login");
);

// login post handle
router.post(
    "/login",
    passport.authenticate("local", 
        successRedirect: "/admin",
        failureRedirect: "/post/login",
        failureFlash: true,
    ),
    function (req, res) 
        console.log("hello");

        res.redirect("/admin");
    
);

module.exports = router;

登录页面

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <base href='/'>
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css"
        integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
    <link rel="stylesheet" href="css/style.css">
    <title>homepage</title>
</head>

<body>
    <nav class="navbar navbar-expand-lg fixed-top navbar-dark bg-dark p-3">
        <h3 class="navbar text-white">Homepage</h3>
        <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarresponsive"
            aria-controls="navbarresponsive" aria-expanded="false" aria-label="Toggle navigation">
            <span class="navbar-toggler-icon"></span>
        </button>

        <div class="collapse navbar-collapse">
            <ul class="navbar-nav ml-auto">
                <li class="nav-item ">
                    <a href="/" class="nav-link">Home</a>
                </li>
                <li class="nav-item ">
                    <a href="/post/register" class="nav-link">Register</a>
                </li>
                <li class="nav-item active">
                    <a href="/post/login" class="nav-link">Login</a>
                </li>
            </ul>
        </div>

    </nav>

    !-- form validation --
    <div class="container m-auto">

        <div class="card card-body gap " style="width:36rem">
            <h4 class="card-title  bg-light font-weight-bold">USER LOGIN</h4>
            #if success_msg
            <h4 class="alert alert-success" id="msg-2">success_msg</h4>
            /if

            #if error
            <h4 class="alert alert-warning" id="msg-3">error</h4>
            /if
            <hr class="bg-dark">
            <form action="/post/login" method="POST">


                <div class="form-group">
                    <label for="email">Email</label>
                    <input type="email" class="form-control" id="email" name="email" placeholder="Enter Email">
                </div>
                <div class="form-group">
                    <label for="password">Password</label>
                    <input type="password" class="form-control" id="password" name="password"
                        placeholder="Enter Password">
                </div>

                <button type="submit" class="btn btn-primary btn-sm text-center">Submit</button>
            </form>
        </div>
    </div>



    !-- footer --
    <footer class="fixed-bottom bg-dark p-2">
        <p class="text-white text-center">Website Copyright &copy; 2021</p>
    </footer>



    <script src="js/main.js"></script>
    <script src="https://code.jquery.com/jquery-3.2.1.slim.min.js"
        integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN"
        crossorigin="anonymous"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js"
        integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q"
        crossorigin="anonymous"></script>
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js"
        integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl"
        crossorigin="anonymous"></script>
</body>

</html>

【问题讨论】:

【参考方案1】:

本地策略的验证回调应该只有 3 个参数(电子邮件、密码、完成)。 我建议删除 req 作为参数,因为它当前保存电子邮件字符串并替换所有参数。

护照配置:

new LocalStrategy(
    ...
    (email, password, done) => 

【讨论】:

以上是关于护照身份验证不适用于 nodejs 和 mysql的主要内容,如果未能解决你的问题,请参考以下文章

nodejs护照身份验证令牌

本地护照不适用于多种型号

身份验证不适用于使用 NodeJS 进行的谷歌云 API 身份验证

NodeJs Express - 将请求参数传递给护照身份验证

如何在 laravel 护照中实现多身份验证

模块导出,nodejs对于护照身份验证需要太长时间