Dans l’article précédent: introduction à feathersjs , nous avons abordé :
- La création d’une api Restful avec featherjs en utilisant Sequelize . On a choisi MySQL comme gestionnaire de base de données.
- Des exemples d’utilisation de service feathers tels que : « create, update, delete, get« ..
- Des requêtes complexes sans toucher au code
- Le tri, le nombre de lignes à récupérer..
Dans cet article, nous présenterons l’authentification d’un utilisateur.
Authentification
Il s’agit de permettre à un utilisateur de s’authentifier grâce à la saisie d’un couple « identifiant/mot de passe ». En étant connecté, il pourra y accéder aux pages accessibles uniquement aux utilisateurs authentifiés.
Nous allons partir sur le même principe que l'authentification avec expressjs .
Comme pour la création d’un type service avec feathers, il est possible de créer un type authentication . Voici la commande
feathers generate authentication
La console nous demande :
- le nom du service qu’on souhaite avoir – on saisit : fos_users
- le choix type de service – on choisit sequelize
- le choix du gestionnaire de base de données – on indique MySQL (MariaDB)
Modification du modèle
Modifions le modèle featherjs/src/models/fos_users.model.js
. Nous allons ajouter les champs décrits dans notre table fos_user
const fosUsers = sequelizeClient.define('fos_users', {
id: {
type: DataTypes.INTEGER(11),
allowNull: false,
primaryKey: true,
autoIncrement: true
},
username: {
type: DataTypes.STRING(180),
allowNull: false
},
username_canonical: {
type: DataTypes.STRING(180),
allowNull: false,
unique: true
},
email: {
type: DataTypes.STRING(180),
allowNull: false
},
email_canonical: {
type: DataTypes.STRING(180),
allowNull: false,
unique: true
},
enabled: {
type: DataTypes.INTEGER(1),
allowNull: false
},
salt: {
type: DataTypes.STRING(255),
allowNull: true
},
password: {
type: DataTypes.STRING(255),
allowNull: false
},
last_login: {
type: DataTypes.DATE,
allowNull: true
},
confirmation_token: {
type: DataTypes.STRING(180),
allowNull: true,
unique: true
},
password_requested_at: {
type: DataTypes.DATE,
allowNull: true
},
roles: {
type: DataTypes.TEXT,
allowNull: false
},
facebook_id: {
type: DataTypes.STRING(255),
allowNull: true
},
facebook_access_token: {
type: DataTypes.STRING(255),
allowNull: true
},
google_id: {
type: DataTypes.STRING(255),
allowNull: true
},
google_access_token: {
type: DataTypes.STRING(255),
allowNull: true
},
twitterid: {
type: DataTypes.STRING(255),
allowNull: true
},
twitter_token: {
type: DataTypes.STRING(255),
allowNull: true
},
nickname: {
type: DataTypes.STRING(255),
allowNull: true
},
first_name: {
type: DataTypes.STRING(255),
allowNull: true
},
last_name: {
type: DataTypes.STRING(255),
allowNull: true
},
profile_picture: {
type: DataTypes.TEXT,
allowNull: true
},
email_rs: {
type: DataTypes.STRING(255),
allowNull: true
},
infos: {
type: DataTypes.TEXT,
allowNull: true
},
country_isoCode: {
type: DataTypes.STRING(10),
allowNull: true
},
country_name: {
type: DataTypes.STRING(255),
allowNull: true
},
city_name: {
type: DataTypes.STRING(255),
allowNull: true
},
location_timeZone: {
type: DataTypes.STRING(255),
allowNull: true
},
browser_ua_name: {
type: DataTypes.STRING(255),
allowNull: true
},
browser_ua_ver: {
type: DataTypes.STRING(255),
allowNull: true
},
browser_ua_family: {
type: DataTypes.STRING(255),
allowNull: true
},
browser_ua_company: {
type: DataTypes.STRING(255),
allowNull: true
},
browser_ua_engine: {
type: DataTypes.STRING(255),
allowNull: true
},
browser_os_name: {
type: DataTypes.STRING(255),
allowNull: true
},
browser_os_family: {
type: DataTypes.STRING(255),
allowNull: true
},
browser_device_name: {
type: DataTypes.STRING(255),
allowNull: true
},
created_at: {
type: DataTypes.DATE,
allowNull: true
},
updated_at: {
type: DataTypes.DATE,
allowNull: true
}
},{
tableName: 'fos_user',
underscored: false,
timestamps: false
}, {
hooks: {
beforeCount(options) {
options.raw = true;
}
}
});
Création d’un utilisateur
On crée un utilisateur dans notre table avec les informations suivantes :
- username: miary
- password: test
On peut créer cet utilisateur en utilisant POSTMAN :
- Méthode : POST
- URL : http://localhost:3030/fos_users
- Dans
Body > x-wwww-form-urlencoded
, on enregistre les champs comme sur cette image: - On clique sur le bouton « SEND«
Les champs supplémentaires tels que : (username_canonical, email_canonical, enabled, roles) sont des champs obligatoires (de type NOT NULL
)
Notre utilisateur a bien été créé comme on peut le voir sur l’image suivante.
Il lui a été attribué l’identifiant "id": 590
. Si on visualise la table, on a :
Connexion avec cet utilisateur
On modifie featherjs/config/default.json
pour spécifier que nous allons utiliser le champ username
pour l’identifiant
"local": {
"entity": "user",
"usernameField": "\username",
"passwordField": "password"
}
Retournons dans POSTMAN :
- Méthode: POST
- URL: http://localhost:3030/authentication/
- Dans
Body > x-wwww-form-urlencoded
, on saisit comme sur cette image - On clique sur le bouton « SEND«
Et voilà, on obtient un joli token comme sur cette image :
Que veut dire ce token? . Pour le décoder, allons copier le code et allons sur ce lien https://jwt.io/ . Collons ensuite le code accessToken dans le champ de gauche. On obtient 3 blocs dans la colonne de droite.
Protection d’une URL
Nous allons protéger une nouvelle URL : http://localhost:3030/api/event
.
Pour cela, nous allons créer un service event
Dans la console, on saisit:
feathers generate service
On remarque une spécificité dans la création de ce service. A la question:
? Does the service require authentication?
On a répondu yes
Une fois le service créé. On ajuste featherjs/src/models/event.model.js
pour faire correspondre les champs définis dans le fichier aux aux champs dans notre table.
…Dans POSTMAN :
- Méthode: GET
- URL : http://localhost:3030/api/event
- Clic sur le bouton « SEND »
Et bim !! message d’erreur
{
"name": "NotAuthenticated",
"message": "No auth token",
"code": 401,
"className": "not-authenticated",
"data": {},
"errors": {}
}
En effet, comme on a veut que l’accès à cette ressource soit uniquement réservé aux utilisateurs authentifés.
Pour remédier à celà, il faut ajouter le token dans le Header
de l’URL.
- Dans Authorization > Puis dans TYPE > On choisit: Bearer Token
- Dans le champ de droite token > On colle le token utilisé plus haut.
- Et on clique sur le bouton « SEND »
Et cela fonctionne comme par magie