我正在尝试在添加员工功能中使用csrf。但是,每当我点击提交时,我总是会收到ForbiddenError:无效的csrf令牌。我不确定我正确执行csrf的方式。
另一方面,我有一个登录和注册表格。工作正常。我为添加员工执行了相同的步骤。
我一直在阅读其他文章,但我听不懂。谁能指出我正确的方法?我真的很感激。
const express = require('express');
const router = express.Router();
const {uploadProduct, uploadForEmployee, uploadForVendor} = require('../upload');
const validation = require('validator');
const bcrypt = require('bcryptjs');
const csrf = require('csurf');
const csrfProtection = csrf();
//Load User model
const User = require('../../models/User');
router.get('/viewEmployee', (req, res) => {
User.find({$or: [{role: 'Admin'}, {role: 'Employee'}] }, (err, doc) => {
res.status(200).render('./admin/viewEmployee', {
user: req.user,
doc: doc,
link: "/admin/employees/"
})
})
});
router.delete('/:email', (req, res) => {
User.deleteOne({email: req.params.email}, (err, user) => {
if(err) {
console.log('Error while deleting product');
} else {
console.log(req.params.email + ' deleted');
res.redirect('/admin/employees/viewEmployee');
}
});
});
router.use(csrfProtection);
router.get('/addEmployee', (req, res) => {
res.render("./admin/employeeForm", {csrfToken: req.csrfToken()});
});
router.post('/addEmployee', uploadForEmployee.single('image'), (req, res) => {
let {name, email, password, phone, address, role} = req.body;
let image = req.file;
let errors = [];
if(!name || !email || ! password || !phone || !address || !role) {
errors.push({msg: 'Please enter all fields.'});
}
if(!image) {
errors.push({msg: 'Please upload a photo of yourself.'});
}
//sanitize input
name = validation.escape(name);
email = validation.escape(email);
password = validation.escape(password);
phone = validation.escape(phone);
address = validation.escape(address);
//Validate email
if(!validation.isEmail(email)){
errors.push({msg: 'Bad email.'})
} else {
email = validation.normalizeEmail(email, [
'all_lowercase', 'gmail_remove_dots','gmail_remove_subaddress', 'gmail_convert_googlemaildotcom',
'outlookdotcom_remove_subaddress', 'yahoo_remove_subaddress', 'icloud_remove_subaddress'
])
}
if (password.length < 6) {
errors.push({ msg: 'Password must be at least 6 characters.' });
}
if (errors.length > 0) {
res.render('./admin/employeeForm', {
errors,
name,
email,
password,
phone,
address,
role,
image,
csrfToken: req.csrfToken()
});
} else {
User.findOne({ email: email }).then(user => {
if (user) {
errors.push({ msg: 'Email already exists.' });
res.render('./admin/employeeForm', {
errors,
name,
email,
password,
phone,
address,
role,
image,
csrfToken: req.csrfToken()
});
} else {
const newUser = new User({
name: name,
email: email,
password: password,
phone: phone,
address: address,
role: role,
imageUrl: '/images/employees/' + image.filename
});
bcrypt.genSalt(10, (err, salt) => {
bcrypt.hash(newUser.password, salt, (err, hash) => {
if (err) throw err;
newUser.password = hash;
newUser
.save()
.then(user => {
req.flash(
'success_msg',
'You are now registered and can log in.'
);
res.redirect('/admin/employees/viewEmployee');
})
.catch(err => console.log(err));
});
});
}
});
}
});
module.exports = router;
这是我的登录和注册功能。这些与csrf配合使用就可以了。
const express = require('express');
const router = express.Router();
const bcrypt = require('bcryptjs');
const passport = require('passport');
const {ensureLoggedIn, ensureLoggedOut} = require('connect-ensure-login');
const validation = require('validator');
const csrf = require('csurf');
const csrfProtection = csrf();
// Load User model
const User = require('../models/User');
//Profile
router.get('/profile', ensureLoggedIn('/users/login'), (req, res, next) => {
res.render('profile')
});
// Logout
router.get('/logout', (req, res) => {
req.logout();
req.flash('success_msg', 'You are logged out.');
res.redirect('/users/login');
});
// Register
router.post('/register', (req, res) => {
let { name, email, password, password2 } = req.body;
let errors = [];
if (!name || !email || !password || !password2) {
errors.push({ msg: 'Please enter all fields' });
}
//sanitize input
name = validation.escape(name);
email = validation.escape(email);
password = validation.escape(password);
password2 = validation.escape(password2);
//Validate email
if(!validation.isEmail(email)){
errors.push({msg: 'Bad email.'})
} else {
email = validation.normalizeEmail(email, [
'all_lowercase', 'gmail_remove_dots','gmail_remove_subaddress', 'gmail_convert_googlemaildotcom',
'outlookdotcom_remove_subaddress', 'yahoo_remove_subaddress', 'icloud_remove_subaddress'
])
}
if (password != password2) {
errors.push({ msg: 'Invalid Password.' });
}
if (password.length < 6) {
errors.push({ msg: 'Password must be at least 6 characters.' });
}
if (errors.length > 0) {
res.render('./home/register', {
errors,
name,
email,
password,
password2,
csrfToken: req.csrfToken()
});
} else {
User.findOne({ email: email }).then(user => {
if (user) {
errors.push({ msg: 'Email already exists.' });
res.render('./home/register', {
errors,
name,
email,
password,
password2,
csrfToken: req.csrfToken()
});
} else {
const newUser = new User({
name,
email,
password
});
bcrypt.genSalt(10, (err, salt) => {
bcrypt.hash(newUser.password, salt, (err, hash) => {
if (err) throw err;
newUser.password = hash;
newUser
.save()
.then(user => {
req.flash(
'success_msg',
'You are now registered and can log in.'
);
res.redirect('/users/login');
})
.catch(err => console.log(err));
});
});
}
});
}
});
// Login
router.post('/login', (req, res, next) => {
passport.authenticate('local', {
successReturnToOrRedirect: '/',
failureRedirect: '/users/login',
failureFlash: true
})(req, res, next);
});
router.use(csrfProtection);
// Login Page
router.get('/login', ensureLoggedOut('/'), (req, res, next) => {
res.render('./home/login', {
csrfToken: req.csrfToken()
})
});
// Register Page
router.get('/register', ensureLoggedOut('/'), (req, res, next) => {
res.render('./home/register', {
csrfToken: req.csrfToken()
})
});
module.exports = router;