Tutoriel Vidéo Système de présence

Télécharger la vidéo Télécharger les sources

Maintenant que l'on a vu le principe des tokens JWT, je vous propose de découvrir comment les utiliser à travers un cas concret : La mise en place d'un système de présence basé sur les websockets. Le principe va être de faire communiquer une application Laravel avec une application websocket écrite avec NodeJS

Emettre le JWT

Pour la partie Laravel nous allons utiliser le système d'authentification par défaut (ce n'est pas le point qui nous intérèsse aujourd'hui).

php artisan make:auth

Les utilisateurs peuvent maintenant s'inscrire et se connecter. Nous allons ensuite permettre aux utilisateurs de se connecter au serveur de websocket et d'envoyer les informations le concernant. Nous allons donc générer un token JWT qui contiendra les informations essentielles :

public function index(\Illuminate\Contracts\Auth\Guard $auth)
{
    $user = $auth->user();
    $token = [
        'user_id' => $user->id,
        'user_name' => $user->name,
        'exp' => time() + 60
    ];
    $token = \Firebase\JWT\JWT::encode($token, getenv('JWTSECRET'));
    return view('home', compact('token'));
}

Ce token sera placé dans notre vue afin d'être récupéré depuis le JavaScript :

<ul id="presence" data-websocket="{{ getenv('WEBSOCKET') }}" data-token="{{ $token }}"></ul>

Maintenant, nous pouvons nous connecter au serveur de websocket et identifier l'utilisateur.

import io from 'socket.io-client'

let presence = document.querySelector('#presence')
if (presence) {
  // On récupère l'adresse du serveur depuis l'html
  let socket = io(presence.dataset.websocket)
  // On se connecte au serveur de websocket
  socket.on('connect', () => {
    // On demande l'identification avec le token reçu
    socket.emit('identify', {
      token: presence.dataset.token
    })
  })
}

Recevoir et vérifier le JWT

Côté NodeJS nous allons recevoir le token et nous allons avoir besoin de le vérifier. On utilisera la librairie jsonwebtoken pour cela.

npm i --save jsonwebtoken

Cette librairie possède une méthode verify qui permet de vérifier le token et qui renvoie le contenu du payload décodé.

io.on('connection', socket => {

  let currentUser = null

  socket.on('identify', ({token}) => {
    try {
      let decoded = jwt.verify(token, process.env.JWTSECRET, {
        algorithms: ['HS256']
      })
      currentUser = {
        id: decoded.user_id,
        name: decoded.user_name,
        count: 1
      }
      let user = users.find(u => u.id === currentUser.id)
      if (user) {
        user.count++
      } else {
        users.push(currentUser)
        socket.broadcast.emit('users.new', {user: currentUser})
      }
      socket.emit('users', {users})
    } catch (e) {
      console.error(e.message)
    }
  })

  socket.on('disconnect', () => {
    if (currentUser) {
      let user = users.find(u => u.id === currentUser.id)
      if (user) {
        user.count--
        if (user.count === 0) {
          users = users.filter(u => u.id !== currentUser.id)
          socket.broadcast.emit('users.leave', {user: currentUser})
        }
      }
    }
  })

})