我想让路由(/主页)仅在用户登录时才能访问,但我无法做到。
基本上,我使用 JWT 和 MongoDB 编写了一个身份验证模块,而现在,我一直坚持让页面只有在登录后才能访问。
它确实有效,令牌存储在本地存储中,并且 authMiddleware 返回成功状态。但问题是,登录时我仍然无法进入 /homepage (它说:页面上需要身份验证) 我想我应该改变我的整个登录验证系统。
我真的迷路了,所以我将提供我的项目的所有文件。然而,最重要的可能是 authMiddleware.js ;服务器.js ; Signin.js 的。
authController.js:
require('dotenv').config();
const jwt = require('jsonwebtoken');
const bcrypt = require('bcrypt');
const User = require('../models/User');
exports.signup = async (req, res) => {
const { name, password } = req.body;
try {
const hashedPassword = await bcrypt.hash(password, 10);
const user = await User.create({ name, password: hashedPassword });
const token = jwt.sign({ id: user.id }, process.env.JWT_SECRET, { expiresIn: '1d' });
res.status(201).json({ token });
} catch (error) {
res.status(500).json({ error: 'Failed to create user' });
}
};
exports.checkAlreadyExists = async (req, res) => {
const { name } = req.body;
try {
const user = await User.findOne({ name });
if (user) {
res.status(200).json({ exists: true });
} else {
res.status(200).json({ exists: false });
}
} catch (error) {
res.status(500).json({ error: 'Failed to check if user exists' });
}
};
exports.login = async (req, res) => {
const { name, password } = req.body;
try {
const user = await User.findOne({ name });
if (!user) {
return res.status(401).json({ error: 'Invalid credentials' });
}
const isMatch = await user.comparePassword(password);
if (!isMatch) {
return res.status(401).json({ error: 'Invalid credentials' });
}
const token = jwt.sign({ id: user.id }, process.env.JWT_SECRET, { expiresIn: '1d' });
res.status(200).json({ token });
} catch (error) {
res.status(500).json({ error: 'Failed to login' });
}
};
authMiddleware.js:
const jwt = require('jsonwebtoken');
const isAuthenticated = (req, res, next) => {
console.log('Authorization Header:', req.headers['authorization']);
const token = req.headers['authorization']?.split(' ')[1];
if (!token) {
console.log('No token found');
return res.status(401).json({ error: 'No token provided' });
}
jwt.verify(token, process.env.JWT_SECRET, (err, decoded) => {
if (err) {
console.log('Token verification failed:', err);
return res.status(401).json({ error: 'Failed to authenticate token' });
}
req.userId = decoded.id;
next();
});
};
module.exports = isAuthenticated;
authRoutes.js:
// authRoute.js
const express = require('express');
const path = require('path');
const { signup, login, checkAlreadyExists } = require('../controllers/authController');
const router = express.Router();
router.post('/signup', signup);
router.post('/checkAlreadyExists', checkAlreadyExists);
router.post('/login', login);
module.exports = router;
服务器.js:
require('dotenv').config();
const express = require('express');
const mongoose = require('mongoose');
const authRoutes = require('./routes/authRoute');
const isAuthenticated = require('./middleware/authMiddleware');
const app = express();
app.use(express.json());
app.use(express.static('public'));
mongoose.connect(process.env.MONGODB_URI, {
useNewUrlParser: true,
useUnifiedTopology: true,
});
app.use('/api/auth', authRoutes);
app.get('/', (req, res) => {
res.sendFile(__dirname + '/public/signup.html');
});
app.get('/verifyToken', isAuthenticated, (req, res) => {
res.status(200).json({ message: 'Token is valid' });
});
app.get('/homepage', isAuthenticated,(req, res) => {
res.sendFile(__dirname + '/public/homepage.html');
})
const PORT = process.env.PORT || 5000;
app.listen(PORT, () => {
console.log(`Server is running on port ${PORT}`);
});
signin.js:
document.getElementById('signin-form').addEventListener('submit', async (event) => {
event.preventDefault();
const name = document.getElementById('name').value;
const password = document.getElementById('password').value;
try {
const response = await fetch('/api/auth/login', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ name, password }),
});
const data = await response.json();
if (response.ok) {
localStorage.setItem('token', data.token);
const isSignedIn = await fetch('/homepage', {
method: 'GET',
headers: {
'Authorization': `Bearer ${data.token}`
}
});
} else {
alert(data.error);
}
} catch (error) {
console.error('Erreur:', error);
alert('Une erreur est survenue. Veuillez réessayer.');
}
});
我知道这不是一件容易的事,所以真的,谢谢你。
PS:其他一些帖子谈到了这一点,但我认为它并不真正适合我的代码。
那是因为你没有经过
isAuthenticated()
中间件;
你可能想要这样的东西;
app.use('/homepage', isAuthenticated);
app.get('/homepage', (req, res) => {
res.sendFile(__dirname + '/public/homepage.html');
});