Node.js、mongodb、bcrypt.js登录系统未正确检查用户密码

p8h8hvxi  于 2023-03-12  发布在  Node.js
关注(0)|答案(2)|浏览(117)

我尝试使用Node.js、mongodb和bcrypt.js创建一个基本的登录系统。注册按预期工作,但用户登录不正常,因为它只对数据库中的第一个用户正确工作,只允许任何其他用户使用第一个用户的密码登录。例如,如果数据库为空,我注册了一个用户,用户名为“John”,密码为“helloworld”。如果我尝试使用这些凭据登录,它看起来会成功,但是如果我创建另一个用户,用户名为“Jane”,密码为“goodbye”,并使用这些凭据登录,程序将返回“Invalid password”。但是,如果我尝试使用凭据“Jane”和“helloworld”登录,程序将告诉我它已经成功。
下面是我的代码:
server.js

const express = require('express')
const path = require('path')
const mongoose = require('mongoose')
const User = require('./models/user')
const bcrypt = require('bcryptjs')
const jwt = require('jsonwebtoken')

// JWT Secret
const JWT_SECRET= 'asnotehuaonteihsonet)()*cgighdnh'

// Connects to the MongoDB database
mongoose.connect('mongodb+srv://anousheh1:xxxxxx@cluster0.mgxhzkn.mongodb.net/?retryWrites=true&w=majority')
const app = express()
app.use(express.json())
app.use(express.urlencoded({extended: true}))
app.use('/', express.static('./public'))

app.post('/api/login', async (req, res) => {
    const {username, password} = req.body
    const user = await User.findOne({username}).lean()

    // Checks to see if user is in database
    if (!user) {
        // return res.json({status: 'error', error: 'Invalid username'})
        return res.status(400).json({error: 'Invalid username'})
        
    }
    // Compares the password input by the user to the hashed password in the database
    if ( await bcrypt.compare(req.body.password, user.password)) {
        const token = jwt.sign({id: user._id, username: user.username}, JWT_SECRET)
        console.log(token)
        return res.status(200).json({status: 200, data: ''})
    }else {
        res.status(400).json({status: 400, error: 'Invalid password'})
    }
   
})

app.post('/api/register/', async (req, res) => {
    const {username, password: plaintext} = req.body
    if (!username || typeof username !== 'string') {
        // return res.json({status:'error', error:'Missing Username'})
        return res.status(400).json({error: 'Invalid Username'})
    }

    if (!plaintext || typeof plaintext !== 'string') {
        return res.status(400).json({error: 'Invalid Password'})
    }

   
    const hashedPassword = (await bcrypt.hash(plaintext, 10))

    // Use schema to create an instance which will be added to the database
    try {
        const response = await User.create({
            name: username,
            password: hashedPassword
        })
        res.json({status: 200})
        console.log(response)
    } catch (error) {
        if(error.code === 11000) {
            // return res.json({status: 'error', error: 'Username Taken'})
            return res.status(400).json({error: 'Username Taken'})
        }
        throw error
    }
})

port = 5000
app.listen(port, () => {
    console.log(`Server Activated on Port ${port}`)
})

./public/script.js

const regForm = document.getElementById('registrationForm')

regForm.addEventListener('submit', registerUser)

async function registerUser(event) {
    event.preventDefault()
    const username = document.getElementById('username').value
    const password = document.getElementById('password').value

 
    const result = await fetch ('/api/register', {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json'
        },
        // stringify turns object literals into JSON
        body: JSON.stringify({
            username,
            password
        })
        
    }).then((res) => res.json())

    
    if (result.status !== 200) {
        alert(result.error)
    }

    console.log(result)
}

./public/scriptLogin.js

const loginForm = document.getElementById('loginForm')

loginForm.addEventListener('submit', loginUser)

async function loginUser (event) {
    event.preventDefault()
    const username = document.getElementById('username').value
    const password = document.getElementById('password').value

    const result = await fetch ('/api/login', {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json'
        },
        body: JSON.stringify({
            name: username,
            password: password
        })
    }).then((res) => res.json())

    if (result.status === 200) {
        console.log(`Token: ${result.data}`)
        alert('Success')
    } else {
        alert(result.error)
        // console.log(user)
        // console.log(error)
    }

}

./models/user.js

const mongoose = require('mongoose')

const UserSchema = new mongoose.Schema({
    name: {
        type: String,
        required: true,
        unique: true
    },
    password: {
        type: String,
        required: true
    }

})

module.exports = mongoose.model('User', UserSchema)
yk9xbfzb

yk9xbfzb1#

您应该将UserSchema更改为:

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

并且create是一个新的User,具有:

const response = await User.create({
    username,
    password: hashedPassword
})
wgeznvg7

wgeznvg72#

错误来自findOne'/api/login',因为集合中没有字段username

const user = await User.findOne({name: username}).lean()

const {username: name, password} = req.body
const user = await User.findOne({name}).lean()
  • 请考虑使用try{}catch(err){}*。

相关问题