如何在nodeJs中使用JWT来保护路由?

问题描述 投票:0回答:1

我想让路由(/主页)仅在用户登录时才能访问,但我无法做到。

基本上,我使用 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:其他一些帖子谈到了这一点,但我认为它并不真正适合我的代码。

node.js database mongodb authentication jwt
1个回答
0
投票

那是因为你没有经过

isAuthenticated()
中间件;

你可能想要这样的东西;

app.use('/homepage', isAuthenticated);

app.get('/homepage', (req, res) => {
    res.sendFile(__dirname + '/public/homepage.html');
});
© www.soinside.com 2019 - 2024. All rights reserved.