在同一页面上登录和注册 NodeJS

时间:2021-03-15 15:30:56

标签: node.js authentication post ejs http-method

我正在建立一个简单的博客网站,但在制作用户身份验证设置部分时遇到了问题。我想要发生的是在同一页面上同时拥有注册表单和登录表单(出于样式原因),但我的问题是,据我所知,您不能在一个页面上有两个 POST 方法。我尝试了多种变通方法,例如使用 PUT 或检查字段是否为空,但这些都让人感觉很笨拙并且实际上不起作用。无论如何,在同一页面上是否有两个功能齐全的表单都响应相同的路由?这是我的方法供参考:

const express = require('express')
const bcrypt = require('bcrypt');
const passport = require('passport');
const router = express.Router()
const app = express()
const User = require('../models/User')

router.get('/', async (req, res) => {
    res.render('pages/account', {
        pageQuery: "Account"
    });
    // const allUsers = await User.find({})
    // console.log(allUsers)
    // User.remove({}, function(err) { 
    //     console.log('collection removed') 
    // });
});

router.post('/', async (req, res) => {
    let name = req.body.userNameSignUp
    let password = req.body.userPasswordSignUp
    let passwordConfirm = req.body.userPasswordSignUpConfirm

    const hashedPassword = await bcrypt.hash(password, 10);

    const newUser = new User({
        userName: name,
        userPassword: hashedPassword
    });

    if (!name || !password) {
        res.render('pages/account', {
            errorMessage: "*Please fill out all the fields",
            pageQuery: "Account"
        });
    } else if (password !== passwordConfirm) {
        res.render('pages/account', {
            errorMessage: "*Passwords do not match",
            pageQuery: "Account"
        });
    } else {
        User.findOne({ userName: name })
            .then(user => {
                if (user) {
                    res.render('pages/account', {
                        errorMessage: "*Username Is Already In Use",
                        pageQuery: "Account"
                    });
                }
            })
    }

    try {
        await newUser.save()
        res.redirect('/account')
    } catch (e) {
        res.render('pages/account', {
            errorMessage: "*Welp... The server's down. Come back later",
            pageQuery: "Account"
        });
    }
});

module.exports = router;

以及我对表单的 ejs 视图:

<!DOCTYPE html>
<html lang="en">
<head>
    <title>Cheese | Account</title>
    <%- include('../partials/linkandsrc'); %>
    <script src="js/signUpToggle.js" defer></script>
</head>
<body>
    <%- include('../partials/header'); %>
    <%- include('../partials/navigation'); %>

    <section class="signInSec">
        <div class="account-container">
            <div class="user signInBx">
                <div class="imgBx">
                    <img src="images/SignUp.jpg" alt="">
                </div>
                <div class="formBx">
                    <form action="/account" method="POST">
                        <h2>Sign Up</h2>
                        <%- include('../partials/errorMessage'); %>
                        <input type="text" name="userNameSignUp" placeholder="Username">
                        <input type="text" name="userPasswordSignUp" placeholder="Password">
                        <input type="text" name="userPasswordSignUpConfirm" placeholder="Confirm Password">
                        <input type="submit" value="Create Account">
                        <p class="signin">Already have an account ? <a href="#" onclick="toggleForm();">Sign In.</a></p>
                    </form>
                </div>
            </div>

            <div class="user signUpBx">
                <div class="formBx">
                    <form action="/account" method="POST">
                        <h2>Sign In</h2>
                        <%- include('../partials/errorMessage'); %>
                        <input type="text" name="userNameLogIn" placeholder="Username">
                        <input type="text" name="userPasswordLogIn" placeholder="Password">
                        <input type="submit" value="Login">
                        <p class="signin">Don't have an account ? <a href="#" onclick="toggleForm();">Sign Up.</a></p>
                    </form>
                </div>
                <div class="imgBx">
                    <img src="images/SignIn.jpg" alt="">
                </div>
            </div>
        </div>
    </section>
</body>
</html>

1 个答案:

答案 0 :(得分:1)

如果您确定要使用相同的路由 (/account) 来处理注册和登录,那么一种方法可能是使用隐藏的 input 字段。< /p>

您可以在注册表单中放置一个隐藏输入,名称为 formType(您可以随意命名,这只是一个示例)和值 signup

<form action="/account" method="POST">
    <h2>Sign Up</h2>
    <%- include('../partials/errorMessage'); %>
    <input type="text" name="userNameSignUp" placeholder="Username">
    <input type="text" name="userPasswordSignUp" placeholder="Password">
    <input type="text" name="userPasswordSignUpConfirm" placeholder="Confirm Password">
    <input type="hidden" name="formType" value="signup">
    <input type="submit" value="Create Account">
    <p class="signin">Already have an account ? <a href="#" onclick="toggleForm();">Sign In.</a></p>
</form>

与登录表单类似,名称为 formType,值为 signin

<form action="/account" method="POST">
    <h2>Sign In</h2>
    <%- include('../partials/errorMessage'); %>
    <input type="text" name="userNameLogIn" placeholder="Username">
    <input type="text" name="userPasswordLogIn" placeholder="Password">
    <input type="hidden" name="formType" value="signin">
    <input type="submit" value="Login">
    <p class="signin">Don't have an account ? <a href="#" onclick="toggleForm();">Sign Up.</a></p>
</form>

然后,在您的路由处理程序中,您可以使用一些逻辑来区分使用接收到的 formType 的注册和登录:

router.post('/', async (req, res) => {
  if ('signup' === req.body.formType) {
    // Server-sided sign-up logic can go here...
  } else if ('signin' === req.body.formType) {
    // Server-sided sign-in logic can go here....
  } else {
    // Something/someone has submitted an invalid form?
  }
}