Coding session 1 - Prise en main Strapijs
3 min read

Coding session 1 - Prise en main Strapijs

Date de la session : 22/03/2021 18h00-23h00

Date de publication : 23/03/2021

Intro

Je souhaite accélérer ma façon de développer des applications web/mobile.

Devoir développer la partie Backend me prend trop de temps. Bien qu'il existe des solutions comme Firebase, Aws Amplify, qui propose des SDKs pour accélérer le développement bien souvent j'ai plus de flexibilité à construire mon backend moi-même. Avec Nest.js le plus souvent.

J'ai décidé de me pencher sur les CMS headless afin de voir s'ils peuvent apporter un gain de productivité. Il y en a deux qui ont retenu mon attention Strapi, et Directus v9. v9, car avant cette version, Directus était codé en PHP https://directus.io/articles/introducing-directus-9.

Objectifs

  • Déployer sur un hosting provider Strapi.
  • Comparer Strapi à Directus v9.
  • Comprendre le workflow de développement jusqu'à la production.
  • Utiliser un stockage distant gratuit pour les médias images, vidéos, audios, documents.

Difficultés rencontrées

Le plugin strapi-provider-upload-firebase ne fonctionne pas correctement. Peut-être devrais-je soumettre une Pull Request pour l'améliorer ? Où créer une marketplace pour acquérir gratuitement ou contre un paiement des plugins/providers pour les plateformes Headless à l'instar de ce qui existe avec Wordpress et ses plugins/extensions.

Heureusement, il y a ce gist.

Je m'en suis inspiré et ça donne ça (à améliorer) :

  1. Utiliser une fonction pour créer l'URL du fichier
  2. Le delete ne fonctionne pas
  3. Améliorer la gestion des logs/erreurs
'use strict';
//https://www.sentinelstand.com/article/guide-to-firebase-storage-download-urls-tokens

/**
 * Module dependencies
 */
 const uuidv4 = require('uuid').v4;

const admin = require("firebase-admin");
let bucket = undefined;

module.exports = {
  provider: 'firebase-storage',
  name: 'firebase-storage',
  auth: {
    serviceAccount: {
      label: 'firebaseConfig JSON',
      type: 'textarea',
    },
    bucket: {
      label: 'Bucketname',
      type: 'text',
    }
  },
  init: (config) => {
    if (!bucket) {
      try {
        admin.initializeApp({
          credential: admin.credential.cert(config.serviceAccount),
          storageBucket: config.bucket
        });
        //console.log("bucket", admin.storage().bucket())
        bucket = admin.storage().bucket();
      } catch (error) {
        console.error("bad"+error)
        throw new Error("incorrect config")
      }
    }

    return {
      upload: async (file) => {
        console.info("file_____________________________________",file.path)
        const path = file.path ? `${file.path}/` : '';
        const uuid = uuidv4();
        try {
          const filename = `${path}${file.hash}${file.ext}`;

          const fileStorage = bucket.file(filename)
           await fileStorage.save(file.buffer, {
            metadata: {
              metadata :{
                firebaseStorageDownloadTokens: uuid,
             }
            },
            destination: `${file.hash}-${file.name}`,
            contentType: file.mime,
            public: false
          });

          file.url = `https://storage.googleapis.com/${config.bucket}/${filename}?alt=media&token=${uuid}`;
        } catch (error) {
          console.log(`Upload failed, try again: ${error}`);
          throw new Error(error)
        }
       
      },
      delete: async (file) => {
        const filename = `${file.hash}-${file.name}`;
        try {
          await bucket.file(filename).delete();
        } catch (error) {
          console.log(`Could not delete: ${error}`);
        }
      }
    };
  }
};

Maintenant, que j'ai ma solution de stockage, une question reste en suspens comment sécuriser l'accès aux medias stockés sur Firebase Storage. Comment garantir que mes fichiers sont accessibles de façon sécurisée tout en étant disponible sur Internet. Par défaut, il faut être authentifié pour accéder aux données stockées. Mais vous avez peut-être remarqué, dans le code lors de l'upload on a la possibilité de rendre un fichier public. Et donc accessible par n'importe qui possédant l'URL. J'aimerais avoir un peu plus de contrôle sur cet accès par exemple avec un jeton qui permettrait de vérifier si on a accès à la ressource. C'est possible et cet article explique tout en détail sentinelstand.com/article/guide-to-firebase-storage-download-urls-tokens.

Je vais me contenter de la solution qui consiste a passer un token sans durée de vie du token. Au pire je pourrai toujours intégrer un Cron qui parcours ma base de données et via le Sdk Firebase Admin demande à mettre à jour les tokens pour chaque image, et mettre à jour mes URLs de medias stockés côté Strapi. Pourquoi pas chaque semaine. Ainsi si par exemple une URL de média venait à être sorti de l'application. L'URL ne serai valide qu'une semaine. Bien sûr, il faudrait s'assurer que chaque média utiliser par des apps clients soit utilisé dynamiquement.

Quelques difficultés a passer la configuration Firebase via des variables d'environnement.

Points positifs

La procédure pour créer ses propres providers est très bien documenté dans Strapi.

Quelques providers sont déjà disponibles dans le repo de Strapi. J'en ai profité pour configurer le provider Sendgrid afin de gérer l'envoi de mail depuis Strapi.

Le déploiement sur Heroku est bien documenté également et se passe correctement.

Nouvelles problématiques

Comment pousser des données contenues en bases de données d'un environnement à l'autre ?

Directus ne semble pas proposer de solution pour customiser ce qu'ils appellent chez eux les storage adapter. Impossible donc pour l'instant d'utiliser Firebase Storage pour la partie stockage des médias avec Directus.

Enjoying these posts? Subscribe for more