TechBook #2 : Création du web service Node.js avec une base de données MongoDB
Avant de commencer, nous rappelons que dans le premier article nous avons installé l’environnement de travail de notre application ainsi nous avons créé un projet Node.js (TechBook #1).
Le but de cet article est de structurer le projet, créer les web services du module authentification (sign up/sign in) et les tester avec un client HTTP comme Postman.
Structure du projet
Afin d’utiliser les bonnes pratiques, on doit ajouter 3 dossiers dans le projet backend :
- modules : contient les modèles utilisés dans la base de données
- routes : on peut déclarer pour chaque modèle un fichier contenant le code du web service lui correspondant.
- uploads : ce dossier contient les fichier téléchargés (images ou vidéos). Il est structuré comme ceci :
uploads/images/users
Création du modèle de l’utilisateur
Après la création des dossiers ci-dessous, on doit ajouter le fichier « user.js » pour définir le modèle de l’utilisateur dans le dossier « modules ». Voici ci-dessous le code permettant de réaliser cela :
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
var bcrypt = require('bcrypt-nodejs');
var pathFolder = 'uploads/images/users/';
const config = require('../config');
const userSchema = new Schema({
email: {
type: String,
required: true
},
password: {
type: String
},
firstName: {
type: String
},
lastName: {
type: String
},
gender: {
type: String
},
age: {
type: String
},
photo: {
type: String
},
createdAt : {
type: Date,
default: Date.now()
},
},
{
toJSON:{virtuals:true}
});
userSchema.methods.getUser=function () {
return({
_id: this._id,
email: this.email,
firstName: this.firstName,
lastName: this.lastName,
gender: this.gender,
age: this.age,
photo: this.photo,
pictureProfile:this.pictureProfile,
createdAt: this.createdAt
})
};
userSchema.virtual('pictureProfile').get(function () {
if (this.photo !== undefined) {
return config.host+pathFolder + this.photo;
}else{
return config.host+pathFolder +'avatar.png';
}
});
userSchema.pre('save', function (next) {
var user = this;
if (this.isModified('password') || this.isNew) {
bcrypt.genSalt(10, function (err, salt) {
if (err) {
return next(err);
}
bcrypt.hash(user.password, salt, null, function (err, hash) {
if (err) {
return next(err);
}
if (user.password){
user.password = hash;
}
next();
});
});
} else {
return next();
}
});
userSchema.methods.comparePassword = function (passw, cb) {
bcrypt.compare(passw, this.password, function (err, isMatch) {
if (err) {
return cb(err);
}
cb(null, isMatch);
});
};
const User = module.exports = mongoose.model('User', userSchema);
On a crypté le mot de passe avec bcrypt-nodejs
. Aussi nous avons ajouté une image de profile par défaut nommé «avatar.png». Elle est téléchargée sous le dossier /uploads/images/users
Quelle est la différence entre les deux champs : photo et pictureProfile ? photo
est le nom de l’image avec extension mais pictureProfile
retourne l’url de l’image qu’on peut lire mais on doit ajouter dans le fichier app.js
ces lignes pour autoriser la lecture des fichiers.
// allow to read files in folder uploads
var publicDir = require('path').join(__dirname,'/Uploads');
app.use('/Uploads', express.static(publicDir));
Développement des web services
SignUp
Commençons maintenant le développement du premier web service, celui qui nous rendra possible la création de comptes utilisateurs.
On doit créer un fichier « users.js
» et on doit l’appeler dans le fameux fichier « app.js
» pour permettre la lecture les url des web services développé dans le fichier « users.js
».
const usersRoutes = require('./routes/users');
// allow to excutes url of web services in such route
app.use('/users', usersRoutes);
Dans ce cas on peut exécuter les web services sous l’url suivant : http://localhost:2500/users/ws_name
Revenons au fichier « users.js
» pour développer le web service inscription.
const express = require('express');
const router = express.Router();
const User = require('../models/user');
var jwt = require('jsonwebtoken');
// signup
router.post('/signUp', function (req, res) {
try {
User.findOne({'email': req.body.email}, function (err, user) {
if (err) {
res.json({
status: 0,
message: ('Error while saving') + err
});
}
if (user) {
res.json({
status: 0,
message: ('Email already used')
});
} else {
var newUser = new User({
firstName: req.body.firstName,
lastName: req.body.lastName,
email: req.body.email,
password: req.body.password,
gender: req.body.gender,
age: req.body.age,
photo: "avatar.png",
createdAt: Date.now(),
});
//save the user
newUser.save(function (err, savedUser) {
if (err) {
res.json({
status: 0,
message: err
});
} else {
var token = jwt.sign(savedUser.getUser(), 'MySecret', {expiresIn: 3600});
res.json({
status: 1,
message: 'signUp successfully',
data: {
user: savedUser.getUser(),
token: token }
})
}
});
}
});
} catch (err) {
console.log(err);
res.json({
status: 0,
message: '500 Internal Server Error',
data: {}
})
}
});
Il ne faut jamais oublier d’exporter le router à la fin de chaque fichier du dossier routes :
module.exports = router;
Maintenant on peut tester notre premier service à travers Postman mais à condition de lancer la commande «mongod
» dans le terminal de votre PC et bien sûr lancer notre serveur via la commande «node app.js
» . Le résultat sera affiché comme ceci :
- le champ
status
retourne 1 s’il y un succès ou 0 si il y a une erreur ou l’email existe déjà - le champ
message
retourne un message - enfin le champ
data
contient l’utilisateur sauvegardé et code JWT contient les données codées.
3-1 : SignIn
Dans la même veine voici le code du login :
//signin user
router.post('/signIn', function (req, res) {
try {
User.findOne({email: req.body.email}, function (err, user) {
if (err) {
res.json({
status: 0,
message: ('erreur auth SignIn') + err
});
}
if (!user) {
res.json({
status: 0,
message: 'Authentication failed. User not found.'
});
} else {
// check if password matches
user.comparePassword(req.body.password, function (err, isMatch) {
if (isMatch && !err) {
// if user is found and password is right create a token
var token = jwt.sign(user.getUser(), 'MySecret', {expiresIn: 3600});
res.json({
status: 1,
message: 'Login successfully ',
data: {
user: user.getUser(),
token: token
}
});
} else {
res.json({
status: 0,
message: 'Authentication failed. Wrong password.'
});
}
});
}
});
} catch (err) {
console.log(err);
res.json({
status: 0,
message: '500 Internal Server Error',
data: {}
})
}
});
Le résultat du login web service est comme ceci :
Finalement je vous conseille de télécharger le code source de notre projet qui contient les fonctionnalités nécessaires pour apprendre le développement avec Node.js sous le ce lien https://github.com/moben-technology/TechBook.
Perspective : Dans l’article suivant nous vous montrons comment consommer les web services dans l’application iOS à travers le pod Alamofire .
A bientôt.