Node.js форма входа в систему через MongoDB

#javascript #node.js #mongodb #express

#javascript #node.js #mongodb #выражать

Вопрос:

Ранее у меня был сайт с формами входа и тому подобным, но без подключения к базе данных. Теперь я подключил ее к mongodb и некоторые вещи заработали. Я могу использовать RESTED для отправки запросов, создания учетных записей и проверки учетных записей в базе данных.

Мне интересно, как я смогу реализовать эту функциональность внутри формы? Где он будет принимать данные формы, запрашивать их через базу данных и входить в систему в случае успеха? То же самое и с регистрацией.

Вот индекс:

 const config = require('config');
var Joi = require('joi');
Joi.objectId = require('joi-objectid')(Joi);
const mongoose = require('mongoose');
const users = require('./routes/users');
const auth = require('./routes/auth');
var express = require("express");
var hbs = require('express-handlebars');
var app = express();
var bodyParser = require('body-parser');

if (!config.get('PrivateKey')) {
    console.error('Error: PrivateKey is not defined.');
    process.exit(1);
}

mongoose.connect('mongodb://localhost/airbnb')
    .then(() => console.log('Now connected to MongoDB!'))
    .catch(err => console.error('Something went wrong', err));

app.use(bodyParser.urlencoded({ extended: true }));

app.set('view engine', 'hbs');

app.engine('hbs', hbs({
    extname: 'hbs', 
    defaultLayout: 'main',
    layoutsDir: __dirname   '/views/layouts',
    partialsDir: __dirname   '/views/partials/' 
}));


app.use('/static', express.static('public'));
app.use(express.json());
app.use('/api/users', users);
app.use('/api/auth', auth);

var HTTP_PORT = process.env.PORT || 8080;

// call this function after the http server starts listening for requests
function onHttpStart() {
    console.log("Express http server listening on: "   HTTP_PORT);
}

// setup a 'route' to listen on the default url path (http://localhost)
app.get("/", function (req, res) {
    res.render('home', {layout: false})
});

// setup another route to listen on /about
app.get("/roomList", function (req, res) {
    res.render('roomList', {layout: false})
});

app.get("/dashboard", function (req, res) {
    res.render('dashboard', {layout: false})
});

// setup http server to listen on HTTP_PORT
app.listen(HTTP_PORT, onHttpStart);
 

вот user.js

 // require mongoose and setup the Schema
var mongoose = require("mongoose");
var Joi = require('joi');
const joiObjectid = require("joi-objectid");

// connect to the localhost mongo running on default port 27017
mongoose.connect("mongodb://localhost/airbnb");

// define the company schema
// register the Company model using the companySchema
// use the web322_companies collection in the db to store documents
var User = mongoose.model('User', new mongoose.Schema({
    email: {
        type: String,
        required: true,
        minlength: 5,
        maxlength: 255,
        unique: true
    },
    password: {
        type: String,
        required: true,
        minlength: 6,
        maxlength: 55555
    }
}));

// validate
function validateUser(user) {
    const schema = Joi.object({
        email: Joi.string().min(5).max(255).required().email(),
        password: Joi.string().min(6).max(55555).required()
    });
    return schema.validate(user);
}

// export

exports.User = User;
exports.validate = validateUser;
 

вот users.js

 const jwt = require('jsonwebtoken');
const config = require('config');
const bcrypt = require('bcrypt');
const _ = require('lodash');
const { User, validate } = require('../models/user');
const express = require('express');
const router = express.Router();

router.post('/', async (req,res) => {
    const { error } = validate(req.body);
    if (error) {
        console.log(req.body.email);
        console.log(req.body.password);
        return res.status(400).send(error.details[0].message);
    }

    let user = await User.findOne({ email: req.body.email });
    if (user) {
        return res.status(400).send('That user already exists!');
    } else {
        user = new User(_.pick(req.body, ['name', 'email', 'password']));
        const salt = await bcrypt.genSalt(10);
        user.password = await bcrypt.hash(user.password, salt);
        await user.save();
        const token = jwt.sign({_id: user._id }, config.get('PrivateKey'));
        res.header('x-auth-token', token).send(_.pick(user, ['_id', 'name', 'email']));
    }
});

module.exports = router;
 

here’s auth.js

 const config = require('config');
const jwt = require('jsonwebtoken');
const Joi = require('joi');
const bcrypt = require('bcrypt');
const _ = require('lodash');
const { User } = require('../models/user');
const express = require('express');
const router = express.Router();

router.post('/', async (req, res) => {
    const { error } = validate(req.body);
    if (error) {
        return res.status(400).send(error.details[0].message);
    }

    let user = await User.findOne({ email: req.body.email });
    if (!user) {
        return res.status(400).send('Incorrect email or password');
    }

    const validPassword = await bcrypt.compare(req.body.password, user.password);
   if (!validPassword) {
       return res.status(400).send('Incorrect email or password');
   } 

   const token = jwt.sign({_id: user._id }, config.get('PrivateKey'));

   res.send(token);
});

function validate(req)
 {
    const schema = Joi.object({
        email: Joi.string().min(5).max(255).required().email(),
        password: Joi.string().min(6).max(55555).required()
    });
    return schema.validate(req);
 }
 
module.exports = router;
 

Вот как выглядит мой режим регистрации в настоящее время:

  <div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel"
        aria-hidden="true">
        <div class="modal-dialog" role="document">
            <div class="modal-content">
                <div class="modal-header">
                    <h5 class="modal-title" id="exampleModalLabel">Registration</h5>
                    <button type="button" class="close" data-dismiss="modal" aria-label="Close">
                        <span aria-hidden="true">amp;times;</span>
                    </button>
                </div>
                <div class="modal-body">
                    <form name="regForm" method="get" action="dashboard" onsubmit="return validateSignupForm()">
                        <div class="form-group mb-0">
                            <label for="formGroupEmail"></label>
                            <input type="email" class="form-control" id="formGroupEmail" placeholder="Email address"
                                name="signupEmail">
                        </div>
                        <div class="form-group mb-0">
                            <label for="formGroupPassword"></label>
                            <input type="password" class="form-control" id="formGroupPassword" placeholder="Password"
                                name="signupPassword">
                        </div>
                </div>
                <div class="modal-footer">
                    <input type="submit" value="Sign up" class="btn btn-danger">
                </div>
                </form>
            </div>
        </div>
    </div>
 
 function validateSignupForm() {

                var signupEmail = document.forms["regForm"]["signupEmail"].value;
                var signupPassword = document.forms["regForm"]["signupPassword"].value;

                if (signupPassword.match(/^(?=.*d)(?=.*[a-z])(?=.*[A-Z]).{6,20}$/)) {
                    return true;
                }
                else {
                    alert('Password must be between 6 and 20 characters and contain at least one number and uppercase letter');
                    return false;
                }

                

            }
 

Ответ №1:

Похоже, что вы прикладываете много усилий ко всему этому коду, тогда как вы можете просто использовать passport.js в частности, passport-local-mongoose, чтобы заставить register / login работать с несколькими строками кода. Для отправки формы вам нужно будет использовать что-то вроде ajax, который может отправлять запросы на ваш внутренний сервер.