В настоящее время я работаю в dev env на своем локальном компьютере, где храню пароли в виде обычного текста, используя MongoDB. Я использую express-jwt
вместе с jsonwebtoken
для передачи пользовательских данных и аутентификации. Я исследовал bcryptjs
и bcrypt
и хотел бы реализовать то, что лучше всего подходит для React и Express, для передачи хешированных паролей в базу данных от клиента. Я нашел ресурсы для серверной части, но ничего для клиентской.
Тогда мой вопрос: какова методология правильного сохранения зашифрованных паролей на моем сервере, когда они передаются от клиента? Как зашифровать пароли на стороне клиента, а затем аутентифицировать серверную часть?
Я читал некоторые статьи, в которых говорилось, что нет необходимости шифровать клиентскую часть из-за ssl, но другие говорят, что шифрование клиентской части абсолютно необходимо. Каков правильный способ и как я могу реализовать его в своем приложении React?
Вы не расшифровываете пароли. Вы запрашиваете у пользователя пароль, затем хешируете его и сравниваете с сохраненным хэшем, который вы сохранили. Если они одинаковы, то (при условии, что у вас есть безопасный алгоритм хеширования) незашифрованные версии также должны быть одинаковыми.
Использование Bcryptjs, Express и MongoDB:
Нет необходимости шифровать клиентскую часть, вы можете передать пароль в виде простого текста на сервер, используя почтовый запрос (обычно через форму).
Предполагая, что у вас есть схема «пользователь», которая выглядит примерно так:
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);
)
При регистрации/регистрации на сервере, где вы обрабатываете запрос, вы должны хэшировать пароль пользователя следующим образом:
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.info(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.info(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);
}
})
редактировать, хэшировать на стороне клиента: Об этом ведутся споры, а в некоторых протоколах даже требуется хешировать пароли на стороне клиента, короче говоря, поскольку SSL уже шифрует все, что передается от клиента к серверу, хеширование на стороне клиента довольно бессмысленно и не является сегодня широко распространены даже в крупных компаниях. Суть в том, что дополнительной безопасностью можно пренебречь, и она не стоит проблем и раскрытия логики хеширования на стороне клиента.
это отличный ответ, но мне любопытно, почему бы вам не зашифровать клиентскую часть?
Спасибо, об этом ведутся споры, а в некоторых протоколах даже требуется хешировать пароли на стороне клиента, короче говоря, потому что SSL уже шифрует все, что перемещается от клиента к серверу, хеширование на стороне клиента довольно бессмысленно. , и, насколько мне известно, сегодня это не принято широко, даже в крупных компаниях. В итоге, на мой взгляд, дополнительной безопасностью можно пренебречь, и она не стоит проблем и раскрытия логики хеширования на стороне клиента.
Круто, спасибо за быстрый ответ. Если вы хотите просто бросить это в свой ответ, я отмечу это.
не могли бы вы объяснить, как это реализовать при использовании реагирующего приложения и node.js? или даже как реализовать это с любым типом внешнего интерфейса. Я просто теряюсь между получением пароля и его проверкой на стороне клиента и сервера.