express - 如何使用节点、EJS、护照和会话有条件地从 2 个导航栏选项中呈现?
问题描述
如何使用节点、EJS、护照和会话有条件地从 2 个导航栏选项中呈现?
我想有条件地从 2 个导航栏选择中呈现。我正在使用 EJS、护照和会话。我尝试了一些东西,但没有任何效果。目标是在客户端未通过身份验证时呈现登录导航栏,如果客户端已使用页面的相同其余部分对两个导航栏进行身份验证,则呈现带有选项的导航栏。
我在这里发布了很多代码,这些代码是我在 Brad Traversy 的视频“Node.js With Passport Authentication |”之后编写的。完整项目”(顺便说一句……谢谢布拉德。大粉丝!)。我相信我接近导航栏文件中的解决方案。我只需要一个真正知道他在做什么的人的帮助(我不知道)。如果你们中的一个好人可以查看下面的文件并告诉我我缺少什么,我将不胜感激。
看起来 Tiger Abrodi 已经问过同样的问题,并且由 Discord 团队解决(请参阅如何使用 ejs 有条件地渲染导航栏)。然而,答案并未显示。我相信这是一个非常有用的解决方案,应该在这里发布给其他人,所以我保证你的解决方案会一直发布在这里供其他人查看。多谢你们!
我的主页;你可以看到我使用“包含”来调用导航栏,这很有效。
<!-- Navigation Bar ----------------------------------->
<%- include('assets/nav-bar'); %>
<!--------- Main Body --------->
<div class="mainBodyContainter mBC2">
<h3>Busca por Marca:</h3>
<ul>
<li>Marca</li>
<li>Año</li>
<li>Modelo</li>
<li>Sub-Modelo</li>
</ul>
<button class="button">Buscar</button>
</div>
<!-- Right *** Anuncio -->
<%- include ('assets/main-ad') %>
<!----------------- Footings ----------------->
<%- include ('assets/footings') %>
我的导航栏;问题:此决策不起作用,因为它一直将用户视为未定义。我可以通过检查下面包含的仪表板来验证用户是否已成功通过身份验证。
<!-- -- Navigation Bar Decision -->
<% if (typeof user === 'undefined') { %>
<!---- Navigation Bar NON AUTHENTICATED CLIENT -------->
<div id="navBarHTML">
<nav>
<ul>
<li><a href="#">Ayuda</a></li>
<li><a href="/users/register">Registrate</a></li>
<li><a href="/users/login">Acceso</a></li>
<li><a href="/">Inicio</a></li>
</ul>
</nav>
</div>
<% } else { %>
<!---- Navigation Bar AUTHENTICATED CLIENT------------->
<div id="navBarHTML">
<nav>
<ul>
<li><a href="#">Ayuda</a></li>
<li><a href="#">Notificaciones</a></li>
<li><a href="#">Mis Publicaciones</a></li>
<li><a href="/users/logout">Salir</a></li>
<li><a href="/">Inicio</a></li>
<li><a>Bienvenido <%= name %></a></li>
</ul>
</nav>
</div>
<% } %>
仪表板
<h1>Dashboard</h1>
<br>
<p>Bienvenido <%= name %></p>
<br>
<a href="/users/logout">Logout</a>
我的 index.js;它将用户名提供给我的仪表板并且工作正常!
const express = require('express');
const router = express.Router();
const { ensureAuthenticated } = require('../config/auth');
// Home page
router.get('/', (req, res) => res.render('home'));
// Dashboard ***PROTECTED FOR NO ACCESS UNLESS LOGGED IN***
router.get('/dashboard', ensureAuthenticated, (req, res) =>
res.render('dashboard', {
name: req.user.name
}));
module.exports = router;
我的 app.js;它工作正常。
const express = require('express');
const expressLayouts = require('express-ejs-layouts');
const mongoose = require('mongoose');
const app = express();
const db = mongoose.connection;
const flash = require('connect-flash');
const session = require('express-session');
const passport = require('passport');
// Passport config
require('./config/passport') (passport);
// Connect to Mongo
mongoose.set('useNewUrlParser', true);
mongoose.set('useUnifiedTopology', true);
mongoose.connect('mongodb://localhost/eyonke_server')
.then(() => console.log('La base de datos de MongoDB conectó correctamente...'))
.catch(err => console.log(err));
// EJS
app.use(expressLayouts);
app.set('view engine', 'ejs');
app.use(express.static(__dirname + '/views'));
// Bodyparser
app.use(express.urlencoded({ extended: false }));
// Express session middleware
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('/', require('./routes/index'));
app.use('/users', require('./routes/users'));
const PORT = process.env.PORT || 5000;
app.listen(PORT, console.log(`El servidor de eYonke esta corriendo en el puerto numero ${PORT}...`));
我的护照配置;工作正常!
const LocalStrategy = require('passport-local').Strategy;
const mongoose = require('mongoose');
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({ email: email })
.then(user => {
if(!user) {
return done(null, false, { message: 'Email no registrado' });
}
// Match password
bcrypt.compare(password, user.password, (err, isMatch) => {
if(err) throw err;
if(isMatch) {
return done(null, user);
} else {
return done(null, false, { message: 'Contraseña incorrecta' });
}
});
})
.catch(err => console.log(err));
})
);
// Session
passport.serializeUser((user, done) => {
done(null, user.id);
});
passport.deserializeUser((id, done) => {
User.findById(id, (err, user) => {
done(err, user);
});
});
}
验证.js;工作正常!
module.exports = {
ensureAuthenticated: function(req, res, next) {
if(req.isAuthenticated()) {
return next();
}
req.flash('error_msg', 'Necesitas entrar a tu cuenta para accesar este recurso');
res.redirect('/'); /*if not authenticated, then redirected to home page*/
}
}
我的 users.js 用于注册和登录/注销;工作正常!
const express = require('express');
const router = express.Router();
const bcrypt = require('bcryptjs');
const passport = require('passport');
//User model
const User = require('../models/User');
//Login page
router.get('/login', (req, res) => res.render('login'));
//Registration page
router.get('/register', (req, res) => res.render('register'));
// Register Handle
router.post('/register', (req, res) => {
const { name, email, password, password2 } = req.body;
let errors = [];
//Check for errors
//Check required fields
if(!name || !email || !password || !password2) {
errors.push({ msg: 'Por favor llena todos los campos'});
}
// Check passwords match
if(password !== password2) {
errors.push({ msg: 'Las contraseñas no son iguales'});
}
// Check password length
if(password.length < 6) {
errors.push({ msg: 'La contraseña debe tener al menos 6 caracteres'});
}
if(errors.length > 0) {
res.render('register', {
errors,
name,
email,
password,
password2
});
} else {
// Validation passed
User.findOne({ email: email })
.then(user => {
if(user) {
// User exists
errors.push({ msg: 'Email ya está registrado en eYonke'});
res.render('register', {
errors,
name,
email,
password,
password2
});
} else {
const newUser = new User({
name,
email,
password
});
// Hash Password
bcrypt.genSalt(10, (err, salt) =>
bcrypt.hash(newUser.password, salt, (err, hash) => {
if(err) throw err;
// set password to hashed
newUser.password = hash;
// Save user
newUser.save()
.then(user => {
req.flash('success_msg', 'Te has registrado exitosamente');
res.redirect('/users/login');
})
.catch(err => console.log(err));
}))
}
});
}
});
// Login handle
router.post('/login', (req, res, next) => {
passport.authenticate('local', {
successRedirect: '/', /*'/dashboard',*/
failureRedirect: '/users/login',
failureFlash: true
})(req, res, next);
});
// Logout handle
router.get('/logout', (req, res) => {
req.logOut();
req.flash('success_msg', 'Tu sessión ha terminado');
res.redirect('/');
});
module.exports = router;
解决方案
我找到了Tiger A。他好心地帮我解决了这个问题。我对代码所做的更改如下:
1.- 在 app.js 我添加了一个全局变量如下:
app.use((req, res, next) => {
res.locals.user = req.user;
next();
});
2.- 在我的导航栏中,我将决策行替换为以下内容:
<% if (!user) { %>
这就是诀窍。现在我可以根据用户是否经过身份验证来决定使用哪个导航栏。
推荐阅读
- ios - 如何使用自定义 UIView(以及内部的转换)重新加载自定义 UICollectionViewCell
- reactjs - 在 React 中编辑值后无法在文本框中输入
- java - 我的 android 应用程序在模拟器上运行并在 android 设备上运行,但登录页面在移动设备上不起作用
- react-native - 无法在深层堆栈屏幕上自定义 React Native 标题标题
- ios - Flutter App 在启动时在 iOS 上崩溃。Xcode 错误“无法识别的选择器”
- macos - 如何在 mac 上安装 apache 基准测试
- python - 将竖线分隔的 .txt 文件转换为字典
- python - Python; 当int太大时如何将字符串转换为int?
- ios - 将 .h 文件添加到桥接头后,项目未构建?为什么?
- r - 如何在 R 中选择数据集的某些行然后在函数中使用?