Node.js 在Express.js中对路由应用授权
我正在尝试开发一个web应用程序,它包括 客户仪表板和管理员仪表板。在管理仪表板中,有用于修改和删除用户的路由。 我必须保证管理员路线的安全。因此,如果用户试图访问例如“/admin/edit user”,服务器将给出403错误 在用户方案中,我有一个名为role的属性。如果用户是客户,则角色的值是客户。如果用户是admin,则角色的值将是admin 我想问的是,在用户登录后,我如何评估用户角色。因此,如果role=customer,用户将被重定向到客户路由,并且将无法访问管理路由。 这是我的密码: 这是passport.js文件,其中包含用于检查用户凭据的本地策略Node.js 在Express.js中对路由应用授权,node.js,express,passport.js,Node.js,Express,Passport.js,我正在尝试开发一个web应用程序,它包括 客户仪表板和管理员仪表板。在管理仪表板中,有用于修改和删除用户的路由。 我必须保证管理员路线的安全。因此,如果用户试图访问例如“/admin/edit user”,服务器将给出403错误 在用户方案中,我有一个名为role的属性。如果用户是客户,则角色的值是客户。如果用户是admin,则角色的值将是admin 我想问的是,在用户登录后,我如何评估用户角色。因此,如果role=customer,用户将被重定向到客户路由,并且将无法访问管理路由。 这是我的密
const LocalStrategy = require('passport-local').Strategy ;
const bcrypt = require('bcryptjs') ;
// Load User Model.
const User = require('../models/User') ;
module.exports = function(passport)
{
passport.use
(
new LocalStrategy
(
{
usernameField : 'email'
},
(email, password, done) =>
{
// Match User.
User.findOne( { where : { email : email} })
.then
(
user =>
{
// If no match.
if(!user)
{
return done
(
null,
false,
{ message : 'Incorrect email or password. Check your email and password or create an account..'}
)
}
// Match the password.
bcrypt.compare
(
password,
user.password,
(err, isMatch) =>
{
if(err) throw err ;
if(isMatch)
{
// TODO remove unnecesarry attributes
return done(null, user) ; /*, {message: 'Logged In Successfully'}*/
}
else
{
return done
(
null,
false,
{ message : 'Incorrect email or password. Check your email and password or create an account..'}
)
}
}
) ;
}
)
.catch(err => console.log(err))
}
)
) ;
passport.serializeUser((user, done) =>
{
done(null, user.id);
}) ;
passport.deserializeUser((id, done) =>
{
User.findByPk(id).then(function(user)
{
done(user.errors, user.get());
}) ;
}) ;
} ;
const express = require('express') ;
const router = express.Router() ;
const bcrypt = require('bcryptjs') ;
const passport = require('passport') ;
// Calling Models
const User = require('../models/User') ;
// Login Page => GET.
router.get('/login', (req, res) =>
{
res.render(
'login',
{
pageTitle : "Login Page"
}
) ;
}) ;
// Login Page => POST.
router.post('/login', (req, res, next) =>
{
const { email, password } = req.body ;
let errors = [] ;
// Check required fields
if (!email || !password)
{
errors.push({ msg: 'Please enter all fields' }) ;
}
// Display Errors.
if (errors.length > 0)
{
res.render(
'login',
{
pageTitle : "Login Page",
errors,
}
) ;
}
else
{
passport.authenticate(
'local',
{
successRedirect: '/admin/dashboard',
failureRedirect: '/login',
failureFlash: true
}
)(req, res, next) ;
}
}) ;
module.exports = router ;
这是用于验证用户凭据的commonRoutes.js文件
const LocalStrategy = require('passport-local').Strategy ;
const bcrypt = require('bcryptjs') ;
// Load User Model.
const User = require('../models/User') ;
module.exports = function(passport)
{
passport.use
(
new LocalStrategy
(
{
usernameField : 'email'
},
(email, password, done) =>
{
// Match User.
User.findOne( { where : { email : email} })
.then
(
user =>
{
// If no match.
if(!user)
{
return done
(
null,
false,
{ message : 'Incorrect email or password. Check your email and password or create an account..'}
)
}
// Match the password.
bcrypt.compare
(
password,
user.password,
(err, isMatch) =>
{
if(err) throw err ;
if(isMatch)
{
// TODO remove unnecesarry attributes
return done(null, user) ; /*, {message: 'Logged In Successfully'}*/
}
else
{
return done
(
null,
false,
{ message : 'Incorrect email or password. Check your email and password or create an account..'}
)
}
}
) ;
}
)
.catch(err => console.log(err))
}
)
) ;
passport.serializeUser((user, done) =>
{
done(null, user.id);
}) ;
passport.deserializeUser((id, done) =>
{
User.findByPk(id).then(function(user)
{
done(user.errors, user.get());
}) ;
}) ;
} ;
const express = require('express') ;
const router = express.Router() ;
const bcrypt = require('bcryptjs') ;
const passport = require('passport') ;
// Calling Models
const User = require('../models/User') ;
// Login Page => GET.
router.get('/login', (req, res) =>
{
res.render(
'login',
{
pageTitle : "Login Page"
}
) ;
}) ;
// Login Page => POST.
router.post('/login', (req, res, next) =>
{
const { email, password } = req.body ;
let errors = [] ;
// Check required fields
if (!email || !password)
{
errors.push({ msg: 'Please enter all fields' }) ;
}
// Display Errors.
if (errors.length > 0)
{
res.render(
'login',
{
pageTitle : "Login Page",
errors,
}
) ;
}
else
{
passport.authenticate(
'local',
{
successRedirect: '/admin/dashboard',
failureRedirect: '/login',
failureFlash: true
}
)(req, res, next) ;
}
}) ;
module.exports = router ;
这是我的app.js文件,其中包含服务器代码:
const express = require('express') ;
const bodyParser = require('body-parser') ;
const expressLayouts = require('express-ejs-layouts') ;
const flash = require('connect-flash') ;
const session = require('express-session') ;
const passport = require('passport');
const path = require('path') ;
const commonRoutes = require('./routes/commonRoutes') ;
const carRoutes = require('./routes/cars') ;
const userRoutes = require('./routes/users') ;
const adminRoutes = require('./routes/admins') ;
const Car = require('./models/Car') ;
const User = require('./models/User') ;
const Trip = require('./models/Trip') ;
// Passport Config
require('./config/passport')(passport) ;
// DB Config.
const db = require('./config/database') ;
// Creating the express application.
const app = express() ;
// Serving static files.
app.use(express.static(path.join(__dirname, 'public'))) ;
// Express Session
app.use(session(
{
secret: 'secret',
resave: true,
saveUninitialized: true,
}
)
) ;
User.hasMany(Trip) ;
Car.hasMany(Trip) ;
User.hasMany(Car) ;
// Connect to MySQL
//db.sync({ force : true})
db.authenticate()
.then( () =>
{
console.log('Database connected...') ;
}
)
.catch( (err) =>
{
console.log(err.message) ;
}
) ;
// EJS
app.use(expressLayouts) ;
app.set('view engine', 'ejs') ;
// Bodyparser
// for parsing application/xwww-
app.use(bodyParser.urlencoded({ extended: false })) ;
// for parsing application/json
app.use(bodyParser.json()) ;
// Express Session
app.use(session({
secret: 'secret',
resave: true,
saveUninitialized: true,
})) ;
// Passport middleware
app.use(passport.initialize()) ;
app.use(passport.session()) ;
// Connect Flash
app.use(flash()) ;
// Global variables
app.use((req, res, next) => {
res.locals.success_msg = req.flash('success_msg');
res.locals.error_msg = req.flash('error_msg');
res.locals.error = req.flash('error');
next();
});
// Routes
app.use('/', commonRoutes) ;
app.use('/car', carRoutes) ;
app.use('/user', userRoutes) ;
app.use('/admin', adminRoutes) ; // Only the admins have permission to access this routes.
const PORT = process.env.PORT || 5000 ;
app.listen(PORT, 'localhost', console.log(`Server is running on port ${PORT}`)) ;
这是包含用户架构的User.js文件:
const Sequelize = require('sequelize') ; // To create models and schema.
const db = require('../config/database');
const User =
db.define
(
'user',
{
id :
{
type : Sequelize.INTEGER(10).UNSIGNED ,
autoIncrement : true,
allowNull : false,
primaryKey : true,
unique: true
},
name :
{
type : Sequelize.STRING,
allowNull : false
},
email :
{
type : Sequelize.STRING,
allowNull : false
},
mobilePhone :
{
type : Sequelize.STRING,
allowNull : false
},
birthDate :
{
type : Sequelize.STRING,
allowNull : false
},
password :
{
type : Sequelize.STRING,
allowNull : false
},
status :
{
type : Sequelize.BOOLEAN, // true if is active // false if is deleted.
allowNull : true
},
role :
{
type : Sequelize.STRING, // Give different access rights if admin or not.
allowNull : false
}
},
{
// By default, sequelize will automatically
// transform all passed model names (first parameter of define) into plural.
// if you don't want that, set the following
freezeTableName : true,
// Disabled timestamps in sequelize.
timestamps : false
}
) ;
module.exports = User ;
我正在寻找一种方法,将授权应用于管理路由。我读到我必须使用JWT(Json Web令牌)。我试图应用JWT,但我做不到
注意:我是nodejs和express.js的新手。大家好!我在GitHub存储库中有一个与此非常类似的项目。在这个项目中,我有三类用户<代码>用户,
管理员
和超级管理员
。通过使用JWT,我能够正确区分用户并指定每个用户的访问级别。这是一个到repo的链接:如果您在repo中实现后遇到任何问题,我们可以与您聊天。这样您就不必浏览整个存储库,以下是一些您可能感兴趣的地方:决定用户状态和访问级别的中间件:登录和注册控制器,我在其中向用户授予令牌:Thank@Tunmee,这很有帮助。但是我想在users.js文件中询问您为什么添加const payload={token:generateToken(formatUserData(user))}代码>为什么我们需要在注册函数中生成令牌。令牌不是仅在用户登录时生成的吗?是的,在用户登录时会向用户提供令牌,但是,不仅在登录期间,您还可以在注册时为用户生成令牌,这样他们就不必在注册后登录。虽然这实际上取决于应用程序,但在特定的应用程序中,在注册时为用户提供令牌是有意义的。