? WA-Tech&DevNews N°12
1 février 2021Intro
1. Action d’introduire, de faire entrer (qqn). 2. Action de faire adopter (une mode, un produit…)
Et c’est repartie pour une news tech ! J’espère que vous avez passez un bon début d’année et je vous souhaite un bon nouveau confinement !
IDE
Toujours plus de code à lire entre les lignes
Et si on profitait de ce début d’année pour mettre à jour ces extensions VS Code ! Pour ceux qui utilisent ce formidable IDE gratuit de Microsoft, je vous propose 12 Plugins !
Javascript
Jaba bien
Aujourd’hui c’est la folie, vous ne me verrez plus pareil après ce que je vous présente. Et si en 2021 ont se passait de React, Angular ou Vue … Oui oui j’ai bien dit un site front-end complexe avec pleins d’interactions, des compilateurs, le support de Typescript et pleins d’autres features sans aucun des 3 Leaders du marché !
Je vous propose 12 alternatives à travers cette article :
Soyons sérieux, il y a peu de chance que vous vous formiez dessus, mais être capable de présenter des alternatives à un client vous permet de montrer que vous n’êtes pas enfermé dans un carcan technologique qui visent à suivre ce que demande le marché.
Simplifier la déclaration de Class avec Typescript ?
Un petit tour sur Typescript? Je vous propose ma technique pour simplifier la déclaration des classes et des interfaces, le tout dans le même fichier avec un constructor simplifié.
Ce code est tellement simple qui peut être généré en ligne de commande avec un batch par exemple en lisant les entitées Java ou PHP
Exemple : avec un fichier user.model.ts
export
interface UserI
{
uid: string;
email: string;
displayName: string;
photoUrl: string;
emailVerified: string;
}
export
class
User implements
UserI
{
uid = ‘’;
email = ‘’;
public displayName = ‘’;
public photoUrl = ’’ ;
public emailVerified = ‘’;
// Constructeur simplifié
constructor(data:
UserI
| {} = {}) {
Object.assign(this, data);
}
}
Pour ceux qui ne le savaient pas, le prototype Object a une méthode “assign” pour attribuer des datas dans un contexte donné en faisant le matching par propriétés.
Le passage de la valeur “{}” en valeur par défaut permet de créer un objet vide en utilisant les valeurs par défaut déclarées sur les propriétés de la Class User lorsque vous ne passez pas de paramètre.
Et dans le cas d’un passage de paramètre on valide l’interface UserI pour être sûr que l’ensemble des champs nécessaire à bien été passé
Fini les constructor à rallonges pour nos Class quand il n’est pas nécessaire de faire un traitement particulier. Et dans le cas contraire on peut directement le faire via un setter par exemple Il suffit de retirer l’implémentation de l’interface dans la Class mais de garder la validation des données du constructor avec l’interface. ( Les données seront donc toujours compatibles entre notre interface et la Class. )
export class User {
_uid: string;
email: string;
public
displayName: string;
public
photoUrl: string;
public
emailVerified: string;
constructor
(data:
UserI
| {} = {}) {
Object.assign(this, data);
}
get
uid() {
return this.uid;
}
set
uid(data:string = ‘’){
if (data && data !== this._uid) { // On check que la valeur est pas déjà la même
this._uid = data;
}
}
}
PHP – Cas d’étude : Changer l’encryptage personnalisé de mots de passe
Op 10, no. 12 – Le tuto de timothée
Récemment, j’ai eu affaire à une problématique intéressante : la refonte d’un projet sur un framework déprécié (Kohana) vers quelque chose de moderne (Symfony 5.2). Le problème principal étant qu’on allait récupérer l’ancienne base de données, avec les utilisateurs et leurs mots de passe. Les mots de passe de l’ancien site étaient encryptés en sha256, symfony recommande plutôt d’utiliser bcrypt pour les mots de passe. Pas de problème, me dis-je, symfony prévoit déjà ce genre de cas avec un système de migration d’encodage. Le principe est simple, vous indiquez à symfony que les mots de passe de certains utilisateurs utilisent un vieil algorithme, et lors de leur prochaine connexion, le mot de passe est ré-encrypté avec le nouvel algorithme. Pour l’utilisateur tout est transparent et son mot de passe reste inchangé.
Problème, notre algorithme en sha256 utilisait une passphrase personnelle pour encoder tous les mots de passe. La documentation Symfony étant assez peu claire sur ce sujet, voici donc comment je m’en suis sorti. Reproduire dans un service le vieil encodage de mot de passe.On va déclarer un nouveau service : LegacyPasswordEncoder, dans notre services.yaml
Ici on a donc :Déclaré un nouveau service appelé app.legacy_pass_encoder (qu’on pourra utiliser plus tard)Qui va aller dans un dossier Security/Encoders/*Qui va prendre en argument notre vieille passphrase, qu’on aura mis ici dans notre .env
*Techniquement c’est le namespace et non l’arborescence mais si vous utilisez des namespaces incohérents avec l’arborescence de vos dossiers, vous avez des problèmes plus importants devant vous.
Regardons maintenant notre fichier LegacyPasswordEncoder.php :
Comme vu précédemment on récupère bien notre passphrase présente ($hashKey ici).
La méthode isPasswordValid vérifie qu’un mot de passe est correct en encodant le mot de passe saisi et en le comparant à la chaîne hashée stockée en BDD dans notre table d’utilisateurs (rien de bien surprenant).
Enfin, la méthode encodePassword encode un mot de passe comme sur l’ancienne version du site avec l’algorithme choisi (ici ‘sha256’, propriété de la classe indiquée plus haut) et notre passphrase secrète :
On voit ici l’utilisation de la fonction hash_hmac avec les paramètre $this->hashMethod (‘sha256’), $raw (le mot de passe saisi par l’utilisateur sur le formulaire de connection, en clair, et $this->hashKey, notre fameuse passphrase secrète.
En soit, on pourrait s’arrêter là et définir cette classe comme étant notre méthode principale d’encodage des mots de passe et nos utilisateurs gardent leur mot de passe encrypté “à l’ancienne” et tout irait bien, mais le reste est encore plus simple. On va maintenant indiquer à symfony que cette classe est l’ancienne façon d’encoder et qu’il faudra encoder les mots de passe des utilisateurs avec une nouvelle méthode :
Détaillons un peu plus ici ce qu’on a fait.
On a défini un encodage baptisé “legacy”, qui correspond au service app.legacy_pass_encoder qu’on a défini plus tôt dans notre service.yaml
On a indiqué que pour l’entité App\Entity\User, on utiliserait celui par défaut de symfony (bcrypt), et qu’il faudrait migrer des vieux mots de passe à partir de l’encodage “legacy”
Et à partir de là, Symfony fait le reste : tous les nouveaux mots de passe seront encodés en bcrypt, et lorsqu’un utilisateur se connecte :
Si son mot de passe est déjà encodé en bcrypt, rien de particulier ne se passe
Si son mot de passe est encodé avec l’encoder “legacy”, il sera mis à jour avec son mot de passe ré-encodé selon l’encoder défini pour
App\Entity\User
, c’est-à-dire celui par défaut (auto) : bcrypt*.
*Il est tout à fait possible de migrer également vers un nouvel encodage personnalisé, si vous en faites un vous-même