未提供令牌 jwt

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

我有一个 Node.js 中的菜谱应用程序和一个 postgreSQL 数据库。我现在在本地主机,我已经被困了两周了。

当用户或管理员连接时,应将其重定向到 /user/profile 或 /admin/profile。 url 是正确的,在检查器的 cookie 部分有一个令牌,但仍然得到

message    "No token provided"

这是我使用 cookie 和令牌进行 Authenticate 的代码。我真的找不到错误,而且时间有限。谢谢您的帮助!

P.S 这是一个没有前端的后端项目。我用EJS。

authMiddleware.js

const jwt = require('jsonwebtoken');
const config = require('../config/config');

function authenticateUser(req, res, next) {
    // Vérifier si un token JWT est fourni dans les en-têtes de la requête
    const token = req.headers.authorization;

    if (!token) {
        console.log('Aucun token fourni.');
        return res.status(401).json({ message: 'No token provided' });
    }

    jwt.verify(token, config.secretKey, (err, decoded) => {
        if (err) {
            console.log('Token invalide :', err);
            return res.status(401).json({ message: 'Invalid token' });
        }

        // Le token est valide, vous pouvez stocker les informations de l'utilisateur dans req.user
        req.user = decoded;
        console.log('Utilisateur authentifié :', req.user);
        next();
    });
}

module.exports = {
    authenticateUser,
};

**authorizeAdmin.js **

const jwt = require('jsonwebtoken');
const config = require('../config/config');
const User = require('../models/User');

function authorizeAdmin(req, res, next) {
    const token = req.cookies ? req.cookies.token : null;
    console.log("Token received in middleware:", token); // log the token

    if (!token) {
        console.log("No token found. Redirecting to /admin/login.");
        return res.status(401).redirect('/admin/login');
    }

    jwt.verify(token, config.secretKey, async (err, decoded) => {
        if (err) {
            console.error('Token verification error:', err);
            return res.status(401).redirect('/admin/login');
        }

        try {
            const admin = await User.findByPk(decoded.id);
            console.log('Admin found:', admin); // Log the found admin

            if (!admin || !admin.isAdmin) {

                console.log('Not an admin user. Redirecting to /admin/login.');
                return res.status(403).redirect('/admin/login');
            }

            req.admin = admin; // Add admin to request object
            console.log('Admin in middleware:', req.admin); // Log the admin object
            next();
        } catch (error) {
            console.error('Error in authorizeAdmin:', error);
            res.status(500).json({ message: 'Internal server error' });
        }
    });

}

module.exports = authorizeAdmin;

authController.js

const bcrypt = require('bcrypt');
const jwt = require('jsonwebtoken');
const User = require('../models/User');
const config = require('../config/config');

// Enregistrement d'un nouvel utilisateur
async function registerUser(req, res) {
    try {
        const { username, password } = req.body;

        // Vérifier si le nom d'utilisateur existe déjà
        const existingUser = await User.findOne({ where: { username } });
        if (existingUser) {
            return res.status(409).json({ message: 'Nom d\'utilisateur déjà existant' });
        }

        // Hacher le mot de passe
        const hashedPassword = await bcrypt.hash(password, 10);

        // Créer le nouvel utilisateur
        const newUser = await User.create({ username, password: hashedPassword });

        // Rediriger vers la page de connexion
        res.redirect('/auth/login');
    } catch (error) {
        console.error('Erreur lors de l\'enregistrement de l\'utilisateur :', error);
        res.status(500).json({ message: 'Erreur interne du serveur' });
    }
}

// Connexion de l'utilisateur
async function loginUser(req, res) {
    try {
        const { username, password } = req.body;

        // Trouver l'utilisateur
        const user = await User.findOne({ where: { username, isAdmin: false } });

        if (!user) {
            return res.status(401).json({ message: 'Nom d\'utilisateur ou mot de passe incorrect' });
        }

        // Comparer les mots de passe
        const passwordMatch = await bcrypt.compare(password, user.password);

        if (!passwordMatch) {
            return res.status(401).json({ message: 'Nom d\'utilisateur ou mot de passe incorrect' });
        }

        // L'utilisateur est connecté, générer un jeton
        const token = jwt.sign({ id: user.id }, config.secretKey, {
            expiresIn: '1h', // Le jeton expirera en 1 heure
        });
        // Définir le jeton en tant que cookie 
        res.cookie('token', token, { httpOnly: true, secure: process.env.NODE_ENV === 'production', sameSite: 'lax' });

        // Rediriger vers la page de profil pour ajouter une recette
        res.redirect('/users/profile');
    } catch (error) {
        console.error('Erreur lors de la connexion de l\'utilisateur :', error);
        res.status(500).json({ message: 'Erreur interne du serveur' });
    }
}

// Fonction pour enregistrer un nouvel admin
async function registerAdmin(req, res) {
    try {
        const { username, password } = req.body;

        // Vérifier si le nom d'utilisateur existe déjà
        const existingUser = await User.findOne({ where: { username } });
        if (existingUser) {
            return res.status(409).json({ message: 'Nom d\'utilisateur déjà existant' });
        }

        // Hacher le mot de passe
        const hashedPassword = await bcrypt.hash(password, 10);

        // Créer un nouvel utilisateur en tant qu'admin
        const newUser = await User.create({ username, password: hashedPassword, isAdmin: true });

        // Rediriger vers la page de connexion admin
        res.redirect('/admin/login');
    } catch (error) {
        console.error('Erreur lors de l\'enregistrement de l\'admin :', error);
        res.status(500).json({ message: 'Erreur interne du serveur' });
    }
}

// Connexion de l'admin
async function loginAdmin(req, res) {
    try {
        const { username, password } = req.body;

        // Trouver l'admin
        const user = await User.findOne({ where: { username, isAdmin: true } });

        if (!user) {
            return res.status(401).json({ message: 'Nom d\'utilisateur ou mot de passe incorrect' });
        }

        // Comparer les mots de passe
        const passwordMatch = await bcrypt.compare(password, user.password);

        if (!passwordMatch) {
            return res.status(401).json({ message: 'Nom d\'utilisateur ou mot de passe incorrect' });
        }

        // Générer un jeton et définir un cookie pour l'admin
        const token = jwt.sign({ id: user.id }, config.secretKey, {
            expiresIn: 86400, // Le jeton expirera en 24 heures
        });
        res.cookie('token', token, { httpOnly: true, secure: process.env.NODE_ENV === 'production', sameSite: 'lax' });

        // Rediriger vers le profil de l'admin
        res.redirect('/admin/adminProfile');
    } catch (error) {
        console.error('Erreur lors de la connexion de l\'admin :', error);
        res.status(500).json({ message: 'Erreur interne du serveur' });
    }
}

// Mise à jour de l'utilisateur
async function updateUser(req, res) {
    try {
        const { id } = req.params;
        const { username, password } = req.body;

        const user = await User.findByPk(id);

        if (!user) {
            return res.status(404).json({ message: 'Utilisateur non trouvé' });
        }

        user.username = username;

        // Hacher le nouveau mot de passe avant de le sauvegarder
        const hashedPassword = await bcrypt.hash(password, 10);
        user.password = hashedPassword;

        await user.save();

        res.json({ message: 'Utilisateur mis à jour avec succès', user });
    } catch (error) {
        console.error('Erreur lors de la mise à jour de l\'utilisateur :', error);
        res.status(500).json({ message: 'Erreur interne du serveur' });
    }
}

// Fonction pour hacher et stocker les mots de passe de tous les utilisateurs
async function hashAndStorePasswords() {
    try {
        const users = await User.findAll();
        let alreadyHashedCount = 0;

        for (let user of users) {
            // Vérifier si le mot de passe est déjà haché
            if (user.password.length === 60) {
                alreadyHashedCount++;
                continue; // Passer à l'itération suivante
            }

            const hashedPassword = await bcrypt.hash(user.password, 10);
            user.password = hashedPassword;
            await user.save();
        }

        console.log(`${alreadyHashedCount} mots de passe étaient déjà hachés.`);
        console.log('Tous les mots de passe nécessaires ont été hachés et stockés.');
    } catch (error) {
        console.error('Erreur dans hashAndStorePasswords :', error);
    }
}

// Appeler la fonction pour hacher et stocker les mots de passe
try {
    hashAndStorePasswords();
} catch (error) {
    console.error('Erreur lors de l\'appel de hashAndStorePasswords :', error);
}

module.exports = {
    registerAdmin,
    loginAdmin,
    registerUser,
    loginUser,
    updateUser,
};

userRoutes.js

const express = require('express');
const router = express.Router();
const userController = require('../controllers/userController');
const authMiddleware = require('../middlewares/authMiddleware'); // Importez le middleware d'authentification

// Définition d'une route GET pour '/profile'. Lorsqu'un client envoie une requête GET à '/profile', la fonction de rappel (callback) spécifiée est exécutée.
router.get('/profile', authMiddleware.authenticateUser, (req, res) => {
    // Vous pouvez accéder à l'utilisateur authentifié via req.user ici.
    res.render('profile', { title: 'Mon profil', user: req.session.user, session: req.session });
});


router.get('/:id', userController.getUser);
router.put('/:id', userController.updateUser);
router.delete('/:id', userController.deleteUser);

module.exports = router;

adminRoutes.js

const express = require('express');
const router = express.Router();
const authorizeAdmin = require('../middlewares/authorizeAdmin');
const authController = require('../controllers/authController');
const User = require('../models/User'); // ajustez le chemin si nécessaire
const recipeController = require('../controllers/recipeController'); // ajustez le chemin si nécessaire



router.get('/recipes', authorizeAdmin, recipeController.getAllRecipes);


router.get('/login', (req, res) => {
    res.render('adminLogin', { title: 'Admin Login' });
});

router.post('/login', authController.loginAdmin);

router.get('/adminProfile', authorizeAdmin, (req, res) => {
    try {
        if (!req.admin) throw new Error('Admin not found');
        res.render('adminProfile', { title: 'Admin Profile', user: req.admin }); // Pass admin as user to the view
    } catch (error) {
        console.error('Error retrieving admin:', error);
        res.status(500).send('Internal server error');
    }
});


router.get('/register', (req, res) => {
    res.render('adminRegister', { title: 'Admin Register' });
});

router.post('/register', authController.registerAdmin);


module.exports = router;

我尝试了我能想到的一切。我的最后一个选择是创建一个前端和节点获取,但我不想要前端

node.js cookies jwt authorization token
1个回答
0
投票

在我看来,您从错误的地方阅读它。

在代码中,您从

authorization
标头检索令牌:

    const token = req.headers.authorization;

但是,你说客户端将其设置在cookie中:

在检查器的 cookie 部分有一个令牌

如果是这种情况,您需要将其作为服务器上的 cookie 来读取。您应该能够通过 ejs 中的

req.headers.cookie
来完成此操作 - 请参阅 如何在 .ejs 视图引擎中打印 cookie

© www.soinside.com 2019 - 2024. All rights reserved.