我就不介绍express和 Postgresql的使用方法了,postgre和其他relational数据库用法都一样
先贴代码create.sql
CREATE TABLE users (
id serial PRIMARY KEY,
name text,
username text UNIQUE,
email text UNIQUE,
password text
);
app.js 你可能需要的所有dependencies,比如我们需要seesion和express等…
require('dotenv').config();
const createError = require('http-errors');
const express = require('express');
const path = require('path');
const cookieParser = require('cookie-parser');
const logger = require('morgan');
const session = require('express-session');
const FileStore = require('session-file-store')(session);
const indexRouter = require('./routes/index');
const usersRouter = require('./routes/users');
const apiRouter = require('./routes/api');
const app = express();
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'hbs');
app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use(session({
store: new FileStore(),
secret: 'keyboard cat',
resave: true,
saveUninitialized: true,
}));
app.use('/', indexRouter);
app.use('/users', usersRouter);
app.use('/api', apiRouter);
// catch 404 and forward to error handler
app.use((req, res, next) => {
next(createError(404));
});
// error handler
app.use((err, req, res) => {
// set locals, only providing error in development
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {};
// render the error page
res.status(err.status || 500);
res.render('error');
});
module.exports = app;
user.js
const express = require('express');
const bcrypt = require('bcrypt');
const db = require('../db');
const router = express.Router();
router.get('/register', (req, res) => {
res.render('register');//获取register.hbs 因为我用的是handlebar
});
router.post('/register', async (req, res) => {
const errors = [];
if (req.body.password !== req.body.passwordConf) {
errors.push('The provided passwords do not match.');
}
if (!(req.body.email && req.body.username && req.body.password && req.body.passwordConf)) {
errors.push('All fields are required.');
}
const selectQuery = 'SELECT * FROM users WHERE username = $1';//如果这个用户已经存在
const selectResult = await db.query(selectQuery, [req.body.username]);
console.log(selectResult);
if (selectResult.rows.length > 0) {
errors.push('That username is already taken.');
}
if (!errors.length) {
const insertQuery = 'INSERT INTO users (username, email, password) VALUES ($1, $2, $3)';//如果没有error,我就在数据库table中插入users的column
const password = await bcrypt.hash(req.body.password, 10);
await db.query(insertQuery, [req.body.username, req.body.email, password]);
res.redirect('login');
} else {
res.render('register', { errors });
}
});
router.get('/login', (req, res) => {
res.render('login');
});
router.post('/login', async (req, res) => {
const errors = [];
const selectQuery = 'SELECT * FROM users WHERE username = $1';
const selectResult = await db.query(selectQuery, [req.body.username]);
if (selectResult.rows.length === 1) {
const auth = await bcrypt.compare(req.body.password, selectResult.rows[0].password);
if (auth) {
[req.session.user] = selectResult.rows;
req.session.cart = [];
req.session.cartCount = 0;
req.session.nextCartId = 1;
console.log(req.session.user);
res.redirect('/');
} else {
errors.push('Incorrect username/password');
res.render('login', { errors });
}
} else {
errors.push('Incorrect username/password');
res.render('login', { errors });
}
});
router.get('/change-password', (req, res) => {
res.render('change');
});
router.post('/change-password', async (req, res) => {
const errors = [];
if (req.body.password !== req.body.passwordConf) {
errors.push('password must match');
}
if (errors.length) {
res.render('change', { errors });
} else {
const hashedPassword = await bcrypt.hash(req.body.password, 10);
const query = 'UPDATE users SET password = $1 WHERE id = $2';
await db.query(query, [hashedPassword, req.session.user.id]);
res.redirect('/users/logout');
}
});
router.get('/logout', (req, res) => {
req.session.destroy();
res.redirect('/');
});
module.exports = router;
除了获取form是用router.get的方法,其他和数据库有交流的都是post方法,需要async/await
安全储存密码我使用的是bcrypt,觉得比较好用,登录和注册使用insert query,重置密码使用update query
记得可以使用req.session.user来验证用户是否登录,这样可以实现用户登录拦截
router.get('/order', async (req, res) => {
if (req.session.user) {
//do something
res.render('order', {
user: req.session.user
})
}
else {
res.redirect('/users/login');
}
})
这样就可以实现如果登录就可以进入order,否则返回登录。