Impossible de remplir le corps de ma demande pour tester la fonctionnalité d'enregistrement à l'aide de Postman *FIXED*
P粉166675898
P粉166675898 2024-04-01 10:09:37
0
1
503

Je développe une application de médias sociaux très simple où les utilisateurs peuvent s'inscrire, se connecter, créer des publications, modifier leur profil et leurs publications, supprimer des publications et se supprimer complètement.

Les jetons via jwt doivent être créés et utilisés de manière appropriée et les utilisateurs téléchargent tous les fichiers pertinents sur cloudinary. Où les photos de profil sont stockées dans le dossier profile_pictures et les publications sont stockées dans le dossier user_posts.

Tout cela a fonctionné lors des tests vendredi dernier. Maintenant, cependant, alors que je m'assois pour réparer les jetons sur le frontend, tout d'un coup, je ne peux plus enregistrer d'utilisateurs. Je suis donc allé au backend, j'ai vérifié le code, je suis allé chez Postman, j'ai testé le routage et il ne remplissait pas le corps de la demande.

Plus de problèmes maintenant, par exemple, le téléchargement de fichiers sur cloudinary ne fonctionne plus non plus, je ne sais pas si cela est dû à la récente mise à jour de l'API, même si leur page indique "dernière mise à jour" le 15 juin », ma dernière inscription et connexion le test a eu lieu le vendredi 16 juin, ce qui m'a fait penser que si ça fonctionnait, ça devrait encore fonctionner maintenant. Mais ce n'est pas le cas

.

Ce n’est pas pour cela que je pose cette question et que je demande de l’aide. J'ai désactivé tout le code lié au téléchargement de fichiers dans l'application pour tester la création d'objets utilisateur mongo db atlas.

C'est là que réside mon problème. Pour une raison qui dépasse mes connaissances et ma compréhension, Postman ne remplira rien avec les données du formulaire, même si tout semble être en ordre, que le type de contenu est correct et que les champs de l'objet utilisateur en cours de création sont corrects.

Si j'utilise une entrée brute dans Postman, cela le remplit simplement. Je suis à bout de nerfs...

Si quelqu'un connaît ce problème, j'apprécierais vraiment votre aide.

Ce qui suit est le code pertinent, veuillez ignorer les lignes de code commentées liées au fichier.

// AUTH CONTROLLER:
// controller for user signup
module.exports.signup = async (req, res, next) => {
    try {
        console.log(req.body, "req body");
        // retrieve user from db by email provided in request body
        const foundUser = await User.findOne({ email: req.body.email });
        console.log(foundUser, "found user");
        // check if foundUser already exists in db
        if (foundUser) {
            res.status(409).json({ message: `Email already in use. Please choose another.` });
        }
        // generate salt and hash for the user password
        const salt = bcrypt.genSaltSync(Number(process.env.SALT_ROUND));
        const hash = bcrypt.hashSync(req.body.password, salt);
        // create a new user object from user model
        const newUser = new User({
            username: req.body.username,
            name: req.body.name,
            email: req.body.email,
            password: hash,
            //profilePicture: req.file.path
        });
        // console.log(req.file, "req file");
        await newUser.save(); // save the new user object to the database
        // upload the profile picture to cloudinary storage
        // const result = await cloudinary.uploader.upload(req.file.path, {
        //     public_id: `profile_pictures/${newUser._id}`,
        // });
        //newUser.profilePicture = result.secure_url;
        //await newUser.save(); // update newUser with the profilePicture URL
        console.log(newUser, "new user");
        // generate a signup token
        // const token = jwt.sign({ newUserId: newUser._id, newUserName: newUser.username, newUserProfilePicture: newUser.profilePicture }, process.env.JWT_SECRET, {
        //     expiresIn: '5m' // expires in 5 minutes (in case signup was erroneous)
        // });
        // store the token as a cookie
        // res.cookie('jwt', token, {
        //     httpOnly: true
        // });
        // respond with the newly created user object and the created token
        res.status(201).json({ message: `User created successfully!`, user: newUser });
    } catch (err) {
        next(err);
    };
};
// AUTH ROUTE:
// import dependencies
const express = require('express')
const authController = require('../controllers/authController')
//const authHandler = require('../middlewares/authHandler')

// create new router object
const router = express.Router()

// import controllers
router.post('/signup', authController.signup)
//router.post('/login', authController.login)
//router.get('/logout', authHandler.checkUser, authController.logout)

module.exports = router
// USER MODEL:
const mongoose = require("mongoose")
const bcrypt = require("bcrypt")

const UserSchema = new mongoose.Schema({
  email: { type: String, required: true, unique: true },
  password: { type: String, required: true },
  name: { type: String, required: true },
  username: { type: String, unique: true },
  //profilePicture: { type: String },
})

// usually you hash/salt inside the appropriate model; like our userModel here.
//
// but we save the user-object twice for following two reasons:
// - the regular data of the user-object gets saved to our mongoDB atlas database.
// - and the profile picture gets uploaded and saved in an appropriate folder to cloudinary.
//
// this triggers the password hash twice, which in return falsifies the user password on login attempt.
// therefore we ignore the code snippet below and directly salt and hash in our authController.
//
// hash and salt user password before saving to database
// UserSchema.pre("save", async function (next) {
// const salt = await bcrypt.genSalt();
// this.password = await bcrypt.hash(this.password, salt);
// next();
// });

// pre-hook for updating password field
UserSchema.pre('findOneAndUpdate', function (next) {
  const update = this.getUpdate()
  if (update.password) {
    bcrypt.hash(update.password, Number(process.env.SALT_ROUND), function (err, hash) {
      if (err) return next(err)
      update.password = hash
      next()
    })
  }
})

// compare the password entered by the user with the hashed password in the database
UserSchema.methods.comparePassword = function (candidatePassword, cb) {
  bcrypt.compare(candidatePassword, this.password, function (err, isMatch) {
    if (err) return cb(err) //cb(err) passes errors down to error handler the same way next(err) does
    cb(null, isMatch)
  })
}

const User = mongoose.model("User", UserSchema)

module.exports = User
// SERVER:
// import dependencies
const cors = require('cors');
const express = require('express');
const cookieParser = require('cookie-parser');

// import routes (modules)
const authRoute = require('./routes/authRoute');
const userRoute = require('./routes/userRoute');
const postRoute = require('./routes/postRoute');

const app = express(); // initialize express

// import middlewares
const { connectMongoDB } = require('./lib/mongoose'); // destruct mongoDB connector
const { errorHandler } = require('./middlewares/errorHandler'); // destruct errorHandler

// allow requests from specified origins with specific methods
const whitelist = [process.env.FRONTEND_URL, 'https://www.arii.me'];

// add cors options
const corsOptions = {
  origin: (origin, callback) => {
    if (whitelist.indexOf(origin) !== -1 || !origin) {
      callback(null, true);
    } else {
      callback(new Error('CORS issues'));
    };
  },
  credentials: true,
};

// enable cross-origin resource sharing with specified options for the express app
app.use(cors(corsOptions));

// parse incoming cookies and make them accessible in req.cookies
app.use(cookieParser());

// enable parsing of incoming JSON data in the request body by the express app
app.use(express.json());

app.use(express.urlencoded({ extended: false }));

// define routes
app.use('/auth', authRoute);
app.use('/users', userRoute);
app.use('/posts', postRoute);

// define middlewares
connectMongoDB();
app.use(errorHandler); // error handler must be last invoked middleware

// listen to server
app.listen(process.env.PORT || 3003, () => {
  console.log(`Server up and running at ${process.env.PORT}`);
});
// MONGOOSE:
// import dependencies
const mongoose = require('mongoose');
require('dotenv').config();

// destruct envs
const { DB_USER, DB_PASS, DB_HOST, DB_NAME } = process.env;

// atlas connection string
const mongoURI = `mongodb+srv://${DB_USER}:${DB_PASS}@${DB_HOST}/${DB_NAME}?retryWrites=true&w=majority`;

// middleware function for handling connections to the mongoDB atlas database
module.exports.connectMongoDB = async () =>{
    try {
        await mongoose.connect(mongoURI, {
            useNewUrlParser: true,
            useUnifiedTopology: true,
        });
        console.log(`Connected to MongoDB Atlas!`);
    } catch (err) {
        console.log(`Couldn't Connect to MongoDB Atlas!`);
        next(err);
    }
}

Désolé si c'est trop, mais c'est tout le code pertinent et j'ai perdu la tête. Je sais que ce n'est pas sage de divulguer ENV, mais ce n'est qu'un exercice pour moi, donc je n'ai aucun scrupule à partager ENV.

J'apprécie vraiment toutes les opinions sur ce sujet.

Mise à jour :

J'ai résolu le problème où le corps de la requête n'était pas renseigné avec le code suivant :

// In the auth route I imported multer:
const multer = require('multer')
const upload = multer()
// Then I added a method to the auth route before signup is called:
router.post('/signup', upload.none(), authController.signup)
// I have also forfeited any file upload during signup
// and replaced them with a default image in my cloudinary assets.
// Here's the updated userModel profilePicture field:
profilePicture: { type: String, default: 'res.cloudinary.com/ddb2abwuu/image/upload/v1687256495/…' }

En suivant ces étapes, le corps de la requête est désormais correctement rempli et je peux également utiliser les données du formulaire Postman et créer à nouveau l'utilisateur sur le frontend.

Les utilisateurs peuvent choisir de modifier la photo de profil par défaut ultérieurement en téléchargeant leur propre profil via patcher. D'autres sites Web gèrent l'acquisition d'utilisateurs de la même manière.

Ne me demandez pas pourquoi je dois subitement faire cette gymnastique mentale, même si tout fonctionne aussi bien qu’il y a quelques jours, nous y sommes.

Je soupçonne fortement qu'au moins un des packages et dépendances que j'utilise avait une sorte de mise à jour de l'API qui m'a complètement gâché.

Pour l'instant, ce ticket est désormais résolu. J'espère que cela sera utile à tous ceux qui rencontreront le même problème étrange à l'avenir.

P粉166675898
P粉166675898

répondre à tous(1)
P粉021553460

Jusqu'à présent, j'ai trouvé une solution à laquelle je n'arrive pas à croire : dans mon authRoute, je dois explicitement importer multer puis créer

const multer = require('multer')
const upload = multer()

Puis précisez dans le parcours d'authentification :

router.post('/signup', upload.none(), authController.signup)

J'ai également abandonné tout téléchargement de fichiers lors de l'inscription et j'ai simplement ajouté manuellement la photo de profil par défaut à mes actifs cloudinaires et je l'ai ajoutée à mon modèle d'utilisateur :

profilePicture: { type: String, default: 'res.cloudinary.com/ddb2abwuu/image/upload/v1687256495/…' }

L'inscription et la connexion fonctionneront donc à nouveau.

En suivant ces étapes, le corps de la requête est désormais correctement rempli et je peux également utiliser les données du formulaire Postman et créer à nouveau l'utilisateur sur le frontend.

Les utilisateurs peuvent choisir de modifier la photo de profil par défaut ultérieurement en téléchargeant leur propre profil via patcher. D'autres sites Web gèrent l'acquisition d'utilisateurs de la même manière.

Ne me demandez pas pourquoi je dois subitement faire cette gymnastique mentale, même si tout fonctionne aussi bien qu’il y a quelques jours, nous y sommes.

Je soupçonne fortement qu'au moins un des packages et dépendances que j'utilise avait une sorte de mise à jour de l'API qui m'a complètement gâché.

À partir de maintenant, ce problème est désormais résolu. J'espère que cela sera utile à tous ceux qui rencontreront le même problème étrange à l'avenir.

Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal