Rumah > Soal Jawab > teks badan
Saya sedang membangunkan aplikasi media sosial yang sangat mudah di mana pengguna boleh mendaftar, log masuk, membuat siaran, mengedit profil dan siaran mereka, memadamkan siaran dan memadamkan diri mereka sepenuhnya.
Token melalui jwt harus dibuat dan digunakan dengan sewajarnya dan pengguna memuat naik semua fail yang berkaitan ke cloudinary. Di mana gambar profil disimpan dalam folder profile_pictures dan siaran disimpan dalam folder user_posts.
Semua ini berkesan apabila diuji pada Jumaat lalu. Kini, bagaimanapun, semasa saya duduk untuk membetulkan token pada bahagian hadapan, tiba-tiba saya tidak lagi boleh mendaftarkan pengguna. Jadi saya pergi ke bahagian belakang, menyemak kod, pergi ke Posmen, menguji penghalaan dan ia tidak mengisi badan permintaan.
Lebih banyak isu sekarang, sebagai contoh, muat naik fail ke cloudinary juga tidak lagi berfungsi, saya tidak tahu sama ada ini disebabkan oleh kemas kini API baru-baru ini, walaupun halaman mereka mengatakan "terakhir dikemas kini" 15 Jun ”, pendaftaran dan log masuk terakhir saya ujian adalah pada hari Jumaat 16 Jun, yang membuat saya berfikir bahawa jika ia berfungsi, ia sepatutnya masih berfungsi sekarang
Semua ini bukan sebab saya bertanya soalan ini dan meminta bantuan. Saya telah melumpuhkan semua kod berkaitan muat naik fail dalam aplikasi untuk menguji penciptaan objek pengguna mongo db atlas.Di sinilah letak masalah saya. Atas sebab tertentu yang di luar pengetahuan dan pemahaman saya, Posmen tidak akan mengisi apa-apa dengan data borang, walaupun semuanya kelihatan teratur, jenis kandungan adalah betul dan medan objek pengguna yang dibuat adalah betul.
Jika saya menggunakan input mentah dalam Posmen ia hanya mengisinya. Saya dah habis akal...
Jika ada sesiapa yang tahu tentang masalah ini, saya amat menghargai bantuan anda.
Berikut ialah kod yang berkaitan, sila abaikan baris kod berkaitan fail yang diulas.
// 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); } }Maaf jika ini terlalu banyak, tetapi ini semua kod yang berkaitan dan saya hilang akal. Saya tahu adalah tidak bijak untuk mendedahkan ENV, tetapi ini hanya latihan untuk diri saya sendiri, jadi saya tidak ragu-ragu untuk berkongsi ENV.
Saya sangat menghargai semua pendapat tentang perkara ini.
Kemas kini:
Saya telah membetulkan isu di mana badan permintaan tidak diisi dengan kod berikut:
// 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/…' }Dengan mengikuti langkah ini, ia kini mengisi badan permintaan dengan betul dan saya juga boleh menggunakan data borang Posmen dan mencipta pengguna sekali lagi di bahagian hadapan.
Pengguna boleh memilih untuk menukar gambar profil lalai kemudian dengan memuat naik profil mereka sendiri melalui patcher. Laman web lain mengendalikan pemerolehan pengguna dengan cara yang sama.
Jangan tanya saya mengapa tiba-tiba saya perlu melakukan gimnastik mental ini, walaupun semuanya berfungsi dengan baik seperti beberapa hari lalu, inilah kita.
Saya sangat mengesyaki bahawa sekurang-kurangnya satu daripada pakej dan kebergantungan yang saya gunakan mempunyai beberapa jenis kemas kini API yang benar-benar mengacaukan saya.
Setakat ini, tiket ini kini telah diselesaikan. Semoga ini berguna kepada sesiapa yang menghadapi masalah pelik yang sama pada masa hadapan.
P粉0215534602024-04-02 09:20:01
Setakat ini saya telah menemui penyelesaian yang saya tidak percaya: dalam authRoute saya, saya perlu mengimport multer secara eksplisit dan kemudian mencipta
const multer = require('multer') const upload = multer()
Kemudian nyatakan dalam laluan pengesahan:
router.post('/signup', upload.none(), authController.signup)
Saya juga menyerah pada sebarang muat naik fail semasa pendaftaran dan hanya menambahkan gambar profil lalai secara manual pada aset awan saya dan menambahkannya pada model pengguna saya:
profilePicture: { type: String, default: 'res.cloudinary.com/ddb2abwuu/image/upload/v1687256495/…' }
Jadi pendaftaran dan log masuk akan berfungsi semula.
Dengan mengikuti langkah ini, ia kini mengisi badan permintaan dengan betul dan saya juga boleh menggunakan data borang Posmen dan mencipta pengguna sekali lagi di bahagian hadapan.
Pengguna boleh memilih untuk menukar gambar profil lalai kemudian dengan memuat naik profil mereka sendiri melalui patcher. Laman web lain mengendalikan pemerolehan pengguna dengan cara yang sama.
Jangan tanya saya mengapa tiba-tiba saya perlu melakukan gimnastik mental ini, walaupun semuanya berfungsi dengan baik seperti beberapa hari lalu, inilah kita.
Saya sangat mengesyaki bahawa sekurang-kurangnya satu daripada pakej dan kebergantungan yang saya gunakan mempunyai beberapa jenis kemas kini API yang benar-benar mengacaukan saya.
Setakat ini, isu ini telah selesai. Semoga ini berguna kepada sesiapa yang menghadapi masalah pelik yang sama pada masa hadapan.