Authentification Flow (with JWT)

Formateur: Fabio Ginja

Register

Lors du register, on va enregister l'utilisateur avec au minimum les champs suivant:

{
  email: "example@email.com",
  password: "hashedpasseword",
  passwordVersion: 0
}

Login

Lors du login, on va générer deux tokens (JWT).

Le premier aura une durée de vie courte (quelques minutes) que l'on appellera accessToken. A chaque fois que l'on fera une requête à notre serveur, l'accessToken permettra au serveur de valider que l'utilisateur est identifié et a le droit d'effectuer cette requête.

accessToken

Payload data 
{
  "email": "example@email.com",
}

Login

Un refreshToken, d'une durée plus longue (heures/jours/semaines) qui, tant qu'il sera valide, sera en charge de renvoyer un nouvel accessToken sous certaines conditions.

refreshToken

Payload data 
{
  "email": "example@email.com",
  "passwordVersion": 0
}

passwordVersion est égale à la valeur du champs qui est en base de données.

Request (Profile)

Considérons que l'utilisateur demande à aller sur sa page profil, page nécessitant qu'il soit bien connecté.
Deux cas de figures:

  1. accessToken toujours valide (il n'a pas expiré), le serveur l'authentifie et renvoie les données
  2. accessToken expiré, on va envoyer au serveur notre refreshToken afin qu'il nous donne un nouvel accessToken

Request (Profile)

Le serveur va vérifier si notre refreshToken n'a pas expiré. S'il a expiré, l'utilisateur doit se login à nouveau.

Sinon, la valeur passwordVersion contenu dans notre refreshToken va être comparée à la valeur stockée en base de données.

Deux cas de figures:

  1. la valeur est la même, on renvoie un nouvel accessToken
  2. la valeur ne correspond pas, l'utilisateur doit se login à nouveau

Update Password

Si l'utilisateur met à jour son mot de passe en base de données, on incrémentera passwordVersion en base de données.

Si le refreshToken n'est pas régénéré, on aura deux valeurs différentes de passwordVersion, une dans le refreshToken (restée à 0) et une dans la base de données (passée à 1). Une fois l'accessToken expiré, l'utilisateur devra donc nécessairement s'identifier à nouveau via le login.

{
  email: "example@email.com",
  password: "updatedHashedpasseword",
  passwordVersion: 1
}

Exemple

(Our) Laptop

Login

accessToken (5 minutes)

refreshToken (2 days)

{
  "email": "fabio@email.com"
}
{
  "email": "fabio@email.com",
  "passwordVersion": 0
}

Exemple - Password leaked

Hacker Mobile

Login

accessToken (5 minutes)

refreshToken (2 days)

{
  "email": "fabio@email.com"
}
{
  "email": "fabio@email.com",
  "passwordVersion": 0
}

Exemple - Updating password

(Our) Laptop

Update password in database

database

{
  "email": "fabio@email.com",
  "passwordVersion": 1
}

Exemple - Hacker Request

Hacker Mobile

Request Before accessToken expires

accessToken (5 minutes) - Request Ok

{
  "email": "fabio@email.com"
}

Exemple - Hacker Request

Hacker Mobile

Request After accessToken expires

refreshToken

database

{
  "email": "fabio@email.com",
  "passwordVersion": 0
}
{
  "email": "fabio@email.com",
  "passwordVersion": 1
}

Hacker Logged out 🎉

0 !== 1

Authentification Flow - JWT

By Fabio Ginja

Authentification Flow - JWT

Slides de formation

  • 218