在具有用户身份验证功能的实际应用程序中,将用户密码作为原始字符串存储在数据库中是不切实际的,但最好将密码散列,然后将其存储到数据库中。
null
Node JS加密模块帮助开发者散列用户密码。
例如:
Original Password : portalforgeeks Hashed Password : bbf13ae4db87d475ca0ee5f97e397248a23509fc10c82f 1e3cf110b352c3ca6cc057955ace9d541573929cd7a74a 280a02e8cb549136b43df7704caaa555b38a
密码散列加密模块
为了演示加密模块的使用,我们可以创建一个简单的登录和注册API,并使用Postman进行测试。 我们将使用两个功能:
- 抱歉。随机字节(“长度”): 生成给定“长度”的加密强数据。
- 加密。pbkdf2Sync(“密码”、“盐”、“迭代”、“长度”、“摘要”): 用“salt”对“password”进行哈希运算,迭代次数等于给定的“迭代次数”(更多迭代意味着更安全的密钥),并使用“digest”中给出的算法生成长度等于给定“length”的密钥。
项目依赖关系:
- node JS:用于后端服务器。
- 用于创建服务器的express模块。
- 用于MongoDB连接和查询的mongoose模块。
- 用于散列的加密模块。
- 解析json数据的主体解析器。
执行操作的步骤
- 首先创建一个目录结构,如下所示:
hashApp --model ----user.js --route ----user.js --server.js
- 创建模型/用户。定义用户模式的js文件
// Importing modules
const mongoose = require(
'mongoose'
);
var
crypto = require(
'crypto'
);
// Creating user schema
const UserSchema = mongoose.Schema({
name : {
type : String,
required :
true
},
email : {
type : String,
required :
true
},
hash : String,
salt : String
});
// Method to set salt and hash the password for a user
// setPassword method first creates a salt unique for every user
// then it hashes the salt with user password and creates a hash
// this hash is stored in the database as user password
UserSchema.methods.setPassword =
function
(password) {
// Creating a unique salt for a particular user
this
.salt = crypto.randomBytes(16).toString(
'hex'
);
// Hashing user's salt and password with 1000 iterations,
64 length and sha512 digest
this
.hash = crypto.pbkdf2Sync(password,
this
.salt,
1000, 64, `sha512`).toString(`hex`);
};
// Method to check the entered password is correct or not
// valid password method checks whether the user
// password is correct or not
// It takes the user password from the request
// and salt from user database entry
// It then hashes user password and salt
// then checks if this generated hash is equal
// to user's hash in the database or not
// If the user's hash is equal to generated hash
// then the password is correct otherwise not
UserSchema.methods.validPassword =
function
(password) {
var
.hash = crypto.pbkdf2Sync(password,
this
.salt, 1000, 64, `sha512`).toString(`hex`);
return
this
.hash === hash;
};
// Exporting module to allow it to be imported in other files
const User = module.exports = mongoose.model('User', UserSchema);
- 创建路由/用户。js文件:
// Importing modules
const express = require(
'express'
);
const router = express.Router();
// Importing User Schema
const User = require(
'../model/user'
);
// User login api
router.post(
'/login'
, (req, res) => {
// Find user with requested email
User.findOne({ email : req.body.email },
function
(err, user) {
if
(user ===
null
) {
return
res.status(400).send({
message :
"User not found."
});
}
else
{
if
(user.validPassword(req.body.password)) {
return
res.status(201).send({
message :
"User Logged In"
,
})
}
else
{
return
res.status(400).send({
message :
"Wrong Password"
});
}
}
});
});
// User signup api
router.post(
'/signup'
, (req, res, next) => {
// Creating empty user object
let newUser =
new
User();
// Initialize newUser object with request data
newUser.name = req.body.name,
newUser.email = req.body.email
// Call setPassword function to hash password
newUser.setPassword(req.body.password);
// Save newUser object to database
newUser.save((err, User) => {
if
(err) {
return
res.status(400).send({
message :
"Failed to add user."
});
}
else
{
return
res.status(201).send({
message :
"User added successfully."
});
}
});
});
// Export module to allow it to be imported in other files
module.exports = router;
- 创建服务器。js文件:
// Importing modules
var
express = require(
'express'
);
var
mongoose = require(
'mongoose'
);
var
bodyparser = require(
'body-parser'
);
// Initialize express app
var
app = express();
// Mongodb connection url
// Connect to MongoDB
mongoose.connect(MONGODB_URI);
mongoose.connection.on(
'connected'
, () => {
console.log(
'Connected to MongoDB @ 27017'
);
});
// Using bodyparser to parse json data
app.use(bodyparser.json());
// Importing routes
const user = require(
'./route/user'
);
// Use user route when url matches /api/user/
app.use(
'/api/user'
, user);
// Creating server
const port = 3000;
app.listen(port, () => {
console.log(
"Server running at port: "
+ port);
});
- 运行服务器。js文件使用命令节点服务器。来自hashApp目录的js
- 打开Postman并创建一个到localhost:3000/api/user/signup的post请求,如下所示:
您将得到以下回复:
用户数据存储在数据库中,如下所示:
{ "_id": { "$oid": "5ab71ef2afb6db0148052f6f" }, "name": "geeksforgeeks", "email": "geek@geeksforgeeks.org", "salt": "ddee18ef6a6804fbb919b25f790005e3", "hash": "bbf13ae4db87d475ca0ee5f97e397248a23509fc10c82f1e3cf110 b352c3ca6cc057955ace9d541573929cd7a74a280a02e8cb549136b43df7704caaa555b38a", "__v": 0 }
- 从Postman创建一个到localhost:3000/api/user/login的post请求,如下所示:
您将得到以下回复:
应用:
- 哈希密码在实际应用中是必要的。
- 加密模块使散列易于实现。
- 散列密码可以确保用户的隐私。
参考资料:
- https://nodejs.org/api/crypto.html
- https://nodejs.org/api/crypto.html#crypto_crypto_pbkdf2_password_salt_iterations_keylen_digest_callback
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END