如何使用React MongoDB和Express正确加密和解密密码



目前我在本地机器上的dev-env中工作,在那里我使用MongoDB以纯文本形式存储密码。我使用express-jwtjsonwebtoken来传递用户数据和身份验证。我已经研究了bcryptjsbcrypt,我想实现React和Express中最好的一个,用于将散列密码从客户端传递到数据库。我找到了服务器端的资源,但没有找到客户端的资源。

那么,我的问题是,当加密密码从客户端传递时,在服务器上正确保存加密密码的方法是什么?如何在客户端加密密码,然后在服务器端进行身份验证?

我读过一些文章,说由于ssl,没有必要加密客户端,但其他人说绝对需要加密客户端。正确的方法是什么?我如何在React应用程序上实现它?

使用Bcryptjs、Express和MongoDB:

  1. 不需要加密客户端,您可以使用post请求(通常通过表单(将密码以纯文本形式传递给服务器。

  2. 假设你有一个"用户"模式,看起来像这样:

    const userSchema = new mongoose.Schema({
    email:{type:String,required:true,unique:true},
    password:{type:String,required:true}
    },{collection:'users'}
    const User= mongoose.model("User",userSchema);
    )
    
  3. 在服务器中注册/注册时,在处理请求的地方,你会对用户的密码进行散列,如下所示:

app.post('/signup',async (req,res)=>{
// geting our data from frontend
const {email,password:plainTextPassword}=req.body;
// encrypting our password to store in database
const password = await bcrypt.hash(plainTextPassword,salt);
try {
// storing our user data into database
const response = await User.create({
email,
password
})
return res.redirect('/');
} catch (error) {
console.log(JSON.stringify(error));
if(error.code === 11000){
return res.send({status:'error',error:'email already exists'})
}
throw error
}
})

4.根据登录请求(也将是通过客户端表单发布的(,您将使用bcrpyt.compare((函数比较密码,如果成功,则为用户分配一个JWT,就像这样,此方法假设令牌将存储在Cookie中。

const verifyUserLogin = async (email,password)=>{
try {
const user = await User.findOne({email}).lean()
if(!user){
return {status:'error',error:'user not found'}
}
if(await bcrypt.compare(password,user.password)){
// creating a JWT token
token = jwt.sign({id:user._id,username:user.email,type:'user'},JWT_SECRET,{ expiresIn: '2h'})
return {status:'ok',data:token}
}
return {status:'error',error:'invalid password'}
} catch (error) {
console.log(error);
return {status:'error',error:'timed out'}
}
}
// login 
app.post('/login',async(req,res)=>{
const {email,password}=req.body;
// we made a function to verify our user login
const response = await verifyUserLogin(email,password);
if(response.status==='ok'){
// storing our JWT web token as a cookie in our browser
res.cookie('token',token,{ maxAge: 2 * 60 * 60 * 1000, httpOnly: true });  // maxAge: 2 hours
res.redirect('/');
}else{
res.json(response);
}
})

  1. 我没有提到前端,因为它只包括react中的基本POST请求表单,不需要任何特殊的方法或客户端处理。希望能有所帮助

编辑,散列客户端:关于这一点存在争议,在某些协议中,甚至需要在客户端对密码进行散列,简而言之,因为SSL已经对从客户端到服务器的所有内容进行了加密。在客户端进行散列是毫无意义的,今天甚至连大公司都不被广泛接受。最重要的是,增加的安全性是可以忽略的,不值得麻烦,也不值得向客户端暴露哈希逻辑

您不解密密码。你向用户询问密码,然后对其进行散列,并将其与你保存的存储散列进行比较。如果它们是相同的,那么(假设你有一个安全的哈希算法(未加密的版本也必须是相同的。

最新更新