使用nodejs express mysql登录系统

Posted

技术标签:

【中文标题】使用nodejs express mysql登录系统【英文标题】:Login system with nodejs express mysql 【发布时间】:2021-08-21 02:13:23 【问题描述】:

我有下面的代码,用于使用 nodejs express 和 mysql 的登录系统。注册和登录服务有效,但 logout 无效。另外,如何限制普通用户访问我的页面,以便只有管理员可以访问它们。文件结构: 代码如下: app.js

onst path = require('path');
const express = require('express');
const ejs = require('ejs');
const bodyParser = require('body-parser');
const mysql = require('mysql');
const dotenv = require('dotenv');
const cookieParser = require('cookie-parser');

dotenv.config( path: './.env' );

var flash = require('express-flash');
var session = require("express-session");

const app = express();

// DB connection
const connection = mysql.createConnection(
    host: process.env.DATABASE_HOST,
    user: process.env.DATABASE_USER,
    password: process.env.DATABASE_PASSWORD,
    database: process.env.DATABASE
);

connection.connect(function(error) 
    if (!!error) console.log(error);
    else console.log('CONGRATS! Database Connected! (app)');
);

//set views file
app.set('views', path.join(__dirname, 'views'));

//set public file
app.use(express.static(__dirname + '/public'));

//set view engine
app.set('view engine', 'ejs');

app.use(express.json());

app.use(express.urlencoded( extended: false )); //instead of false

const routes = require('./server/routes/index');

app.use(session(
    cookie:  maxAge: 60000 ,
    store: new session.MemoryStore,
    saveUninitialized: true,
    resave: true,
    secret: 'mysecret'
))

app.use(flash());

// Defining Routes
app.use('/', routes);
app.use('/auth', require('./server/routes/auth'));

// Server Listening
app.listen(3000, () => 
    console.log('Server is running at port 3000');
);

routes/auth.js

const express = require('express');
const authController = require('../controllers/auth');

const auth_router = express.Router();

auth_router.post('/register', authController.register)
auth_router.post('/login', authController.login);

module.exports = auth_router;

routes/index.js

var express = require('express');
const jwt = require('jsonwebtoken');
var router = express.Router();

/* GET home page. */
router.get('/', function(req, res, next) 
    console.log(req.session);
    console.log(req.headers.cookie);
    res.render('home', 
        title: 'Express',
        loggedIn: req.headers.cookie
    );
);

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

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

router.get('/logout', function(req, res) 
    req.session.destroy();
    res.redirect('/');
)

controllers/auth.js

const mysql = require("mysql");
const jwt = require('jsonwebtoken');
const bcrypt = require('bcryptjs');
var flash = require('express-flash');

const db = mysql.createConnection(
    host: process.env.DATABASE_HOST,
    user: process.env.DATABASE_USER,
    password: process.env.DATABASE_PASSWORD,
    database: process.env.DATABASE
);

exports.login = async(req, res) => 
    try 
        const  username, password  = req.body;

        if (!username || !password) 
            req.flash('danger', 'Please provide username and password!');
            return res.status(400).render('login');
        

        db.query('SELECT * FROM users WHERE username = ?', [username], async(error, results) => 
            console.log(results);
            if (!results || !(await bcrypt.compare(password, results[0].password))) 
                req.flash('danger', 'Username or password is incorrect!');
                res.status(401).render('login')
             else 
                const id = results[0].user_id;

                const token = jwt.sign( id , process.env.JWT_SECRET, 
                    expiresIn: process.env.JWT_EXPIRES_IN
                );
                console.log("The token is: " + token);

                const cookieOptions = 
                    expires: new Date(
                        Date.now() + process.env.JWT_COOKIE_EXPIRES * 24 * 60 * 60 * 1000
                    ),
                    httpOnly: true
                
                res.cookie('jwt', token, cookieOptions);
                req.flash('success', 'You logged in successfully');
                res.status(200).redirect("/");
            
        )
     catch (error) 
        console.log(error);
    


exports.register = (req, res) => 
    console.log(req.body);

    const  username, password, passwordConfirm  = req.body;

    db.query('SELECT username FROM users WHERE username = ?', [username], async(error, results) => 
        if (error) 
            console.log(error);
        
        if (results.length > 0) 
            req.flash('danger', 'That username is already in use!');
            return res.render('register');
         else if (password !== passwordConfirm) 
            req.flash('danger', 'Passwords do not match!');
            return res.render('register');
        
        let hashedPassword = await bcrypt.hash(password, 8);
        console.log(hashedPassword);

        db.query('INSERT INTO users SET ?',  username: username, password: hashedPassword , (error, results) => 
            if (error) 
                console.log(error);
             else 
                console.log(results);
                req.flash('success', 'User registered!');
                return res.render('register');
            
        )
    );

views/register.ejs

<!--Navbar Section-->
    <%- include('./partials/header'); %>
        <!--End Navbar Section-->

        <br>
        <% if (messages.danger)  %>
            <div class="alert alert-danger alert-dismissible fade show" role="alert">
                <%- messages.danger %>
                    <button type="button" class="close" data-dismiss="alert" aria-label="Close">
                  <span aria-hidden="true">&times;</span>
                </button>
            </div>
            <%  %>

                <% if (messages.success)  %>
                    <div class="alert alert-success alert-dismissible fade show" role="alert">
                        <%- messages.success %>
                            <button type="button" class="close" data-dismiss="alert" aria-label="Close">
                      <span aria-hidden="true">&times;</span>
                    </button>
                    </div>
                    <%  %>

                        <div class="container mt-4">
                            <div class="card">
                                <div class="card-header">
                                    Register Form
                                </div>
                                <div class="card-body">
                                    <form action="/auth/register" method="POST">
                                        <div class="form-group">
                                            <label for="username">Userame: </label>
                                            <input type="text" class="form-control" id="username" name="username">
                                        </div>
                                        <div class="form-group">
                                            <label for="password">Password: </label>
                                            <input type="password" class="form-control" id="password" name="password">
                                        </div>
                                        <div class="form-group">
                                            <label for="passwordConfirm">Confirm Password: </label>
                                            <input type="password" class="form-control" id="passwordConfirm" name="passwordConfirm">
                                        </div>
                                        <button type="submit" class="btn btn-primary">Register User</button>
                                    </form>
                                </div>
                            </div>
                        </div>

views/login.ejs

<!--Navbar Section-->
    <%- include('./partials/header'); %>
        <!--End Navbar Section-->

        <br>
        <% if (messages.danger)  %>
            <div class="alert alert-danger alert-dismissible fade show" role="alert">
                <%- messages.danger %>
                    <button type="button" class="close" data-dismiss="alert" aria-label="Close">
                  <span aria-hidden="true">&times;</span>
                </button>
            </div>
            <%  %>

                <div class="container mt-4">
                    <div class="card">
                        <div class="card-header">
                            Login Form
                        </div>
                        <div class="card-body">
                            <form action="/auth/login" method="POST">
                                <div class="form-group">
                                    <label for="username">Username: </label>
                                    <input type="text" class="form-control" id="username" name="username">
                                </div>
                                <div class="form-group">
                                    <label for="password">Password: </label>
                                    <input type="password" class="form-control" id="password" name="password">
                                </div>
                                <button type="submit" class="btn btn-primary">Login</button>
                            </form>
                        </div>
                    </div>
                </div>

views/partial/header.ejs

<div class="navbar-collapse collapse w-100 order-3 dual-collapse2">
                <ul class="navbar-nav ml-auto">
                    <li class="nav-item">
                        <!-- <a class="nav-link" href="#" onclick="document.getElementById('id02').style.display='block'">Sign up</a> -->
                        <a class="nav-link" href="/register">Register</a>
                    </li>

                    <li class="nav-item">
                        <!-- <a class="nav-link" href="#" onclick="document.getElementById('id01').style.display='block'">Login</a> -->
                        <a class="nav-link" href="/login">Login</a>
                    </li>
                    <li class="nav-item">
                        <!-- <a class="nav-link" href="#" onclick="document.getElementById('id02').style.display='block'">Sign up</a> -->
                        <a class="nav-link" href="/logout">Logout</a>
                    </li>
                </ul>
            </div>

【问题讨论】:

【参考方案1】:

使用中间件限制用户无需登录即可访问任何页面 我似乎找不到任何注销不起作用的原因,如果您可以提供 git repo 链接,那么我肯定可以帮助您

【讨论】:

以上是关于使用nodejs express mysql登录系统的主要内容,如果未能解决你的问题,请参考以下文章

将 Mysql 与 Nodejs 和 Express 一起使用 (node-mysql)

NodeJS+express+MySQL实现博客系统(入门级)

Nodejs+express+mysql+百度BAE部署node后台

具有express-sessions和express-mysql-session的NodeJS没有设置会话。我搞砸了哪里?

一个简单的nodejs api开发小结

使用 nodejs/express 登录后将用户重定向到 Angular 应用程序