En aplicaciones de la vida real con funcionalidad de autenticación de usuario, no es práctico almacenar la contraseña de usuario como la string original en la base de datos, pero es una buena práctica codificar la contraseña y luego almacenarla en la base de datos.
El módulo criptográfico para Node JS ayuda a los desarrolladores a codificar la contraseña del usuario.
Ejemplos:
Original Password : portalforgeeks Hashed Password : bbf13ae4db87d475ca0ee5f97e397248a23509fc10c82f 1e3cf110b352c3ca6cc057955ace9d541573929cd7a74a 280a02e8cb549136b43df7704caaa555b38a
Hashing de contraseña con módulo Crypto
Para demostrar el uso del módulo Crypto, podemos crear una API simple de inicio de sesión y registro y probarla con Postman.
Usaremos dos funciones:
- cryto.randomBytes(“longitud”): genera datos criptográficamente fuertes de una “longitud” dada.
- crypto.pbkdf2Sync(“contraseña”, “sal”, “iteraciones”, “longitud”, “resumen”): hash “contraseña” con “sal” con un número de iteraciones igual a las “iteraciones” dadas (Más iteraciones significa una clave más segura ) y usa el algoritmo dado en «resumen» y genera una clave de longitud igual a la «longitud» dada.
Dependencias del proyecto:
- Node JS: para servidor backend.
- módulo express para la creación de servidor.
- módulo mongoose para conexión y consultas MongoDB.
- Módulo criptográfico para hashing.
- body-parser para analizar datos json.
Pasos para realizar la operación
- Primero cree una estructura de directorios como se muestra a continuación:
hashApp --model ----user.js --route ----user.js --server.js
- Cree el archivo model/user.js que define el esquema del usuario
// 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);
- Cree el archivo route/user.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;
- Crear archivo server.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);
});
- Ejecute el archivo server.js usando el Node de comando server.js desde el directorio hashApp
- Abra Postman y cree una solicitud de publicación en localhost:3000/api/user/signup como se muestra a continuación:
Obtendrá la respuesta de la siguiente manera:
Los datos del usuario se almacenan en la base de datos de la siguiente manera:
{ "_id": { "$oid": "5ab71ef2afb6db0148052f6f" }, "name": "geeksforgeeks", "email": "geek@geeksforgeeks.org", "salt": "ddee18ef6a6804fbb919b25f790005e3", "hash": "bbf13ae4db87d475ca0ee5f97e397248a23509fc10c82f1e3cf110 b352c3ca6cc057955ace9d541573929cd7a74a280a02e8cb549136b43df7704caaa555b38a", "__v": 0 }
- Desde Postman, cree una solicitud de publicación en localhost: 3000/api/user/login como se muestra a continuación:
Obtendrá la respuesta de la siguiente manera:
Aplicaciones:
- La contraseña hash es necesaria para la aplicación práctica.
- El módulo criptográfico facilita la implementación del hashing.
- Las contraseñas hash garantizan la privacidad del usuario.
Referencias:
- https://nodejs.org/api/crypto.html
- https://nodejs.org/api/crypto.html#crypto_crypto_pbkdf2_password_salt_iterations_keylen_digest_callback
Publicación traducida automáticamente
Artículo escrito por neerajnegi174 y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA