Feathers: Authentification suivante

Créé le 6 oct. 2018  ·  10Commentaires  ·  Source: feathersjs/feathers

J'ai déjà un peu écrit à ce sujet dans la mise à jour de la feuille de route Feathers Crow . Ce numéro est destiné à collecter tous les problèmes connexes que la prochaine version de l'authentification Feathers couvrira.

Cadre indépendant

Avec la version actuelle (Buzzard), le noyau de Feathers est devenu totalement indépendant du framework, cependant, le plugin d'authentification enregistre toujours certains middleware Express. Dans la prochaine version, ce middleware passera à @feathersjs/express et rendra le noyau d'authentification également indépendant du framework. Cela permettra de nouveaux transports comme Koa ou MQTT.

Authentification de socket améliorée

Actuellement, les websockets sont authentifiés et déconnectés via un mécanisme d'événement personnalisé. Cela causait certains problèmes (par exemple, des erreurs « Pas de jeton d'authentification » peu fréquentes), en particulier autour d'une reconnexion fiable des deux côtés, le serveur et le client.

Client d'authentification amélioré

Cela supprimera la dépendance vis-à-vis du jeton d'accès avec état et gérera avec élégance la réauthentification du socket.

Plus de cookies, oAuth amélioré

Feathers est une bibliothèque permettant de créer des API à l'aide de JWT pour l'authentification. Le seul cas où une configuration normale de Feathers utilise des cookies consiste à transmettre le JWT au navigateur après un flux d'authentification oAuth (Facebook, Google, etc.). Le nouveau client oAuth et d'authentification n'utilisera plus de cookies et divisera le flux oAuth en deux parties au lieu d'essayer de tout faire en même temps. Le jeton d'accès oAuth sera défini dans un hachage d'URL convivial (uniquement accessible localement) qui peut ensuite être échangé contre un JWT à l'aide du mécanisme d'authentification standard de Feathers.

Meilleure gestion des options

Tous les paramètres d'authentification seront désormais évalués au moment de l'exécution, il est donc possible de les définir dynamiquement et il n'y aura pas d'erreurs pour les options qui ne sont pas nécessaires. Il permettra également de passer un service d'authentification personnalisé.

Actualiser les jetons et liste noire

Au lieu d'autoriser l'actualisation avec le JWT existant, le service d'authentification standard renverra désormais également un jeton d'actualisation de plus longue durée. La liste noire des jetons doit encore être implémentée manuellement mais sera plus facile à intégrer via les méthodes du nouveau service d'authentification.

Authentication Breaking Change

Commentaire le plus utile

Vous pouvez voir les progrès actuels dans la branche principale et je publierai un article de blog lorsque les bêta-testeurs pourront l'essayer. Le statut est :

| Module | Code | Documents | CLI
| --- |:---:|:---:|---:|
| @feathersjs/authentification | | 100% | |
| @feathersjs/authentification-local | | 80% | |
| @featherjs/authentification-oauth | | 90%| |
| @feathersjs/authentication-client | | 80%| |

Tous les 10 commentaires

Déprécier le passeport

Cette discussion a commencé dans #844 et dans https://github.com/feathersjs/feathers/issues/844#issuecomment -390123148 ​​résume les raisons pour lesquelles cela se produit. En bref, il n'y a pas eu beaucoup de développement dans PassportJS en particulier autour des frameworks de prise en charge autres qu'Express et la plupart des autres frameworks HTTP comme Koa ou Hapi sont passés à utiliser des bibliothèques d'authentification plus flexibles et minimalistes (comme https://github.com/simov/grant pour oAuth). Il s'est également avéré qu'il n'y a que quatre types de stratégies qui sont vraiment nécessaires :

  • Local (nom d'utilisateur/mot de passe)
  • JWT
  • oAuth (+ jeton d'accès oAuth)
  • Clé API

Sans avoir à contourner Passport, Feathers peut facilement s'asseoir au-dessus de n'importe quelle bibliothèque HTTP et de tout autre mécanisme de transport (comme les connexions MQTT ou même P2P) avec une séparation claire des préoccupations et fournir un mécanisme d'authentification beaucoup plus facile à comprendre et à personnaliser.

Utilisation de params.authentication

Du côté de Feathers, la définition de params.authentication dans un appel de service sera le _seul_ moyen de fournir des informations d'authentification. params.authentication contiendra les informations nécessaires pour authentifier l'appel de service et sera au format par exemple { strategy: 'local', email: 'email', password: 'password' } qui est déjà utilisé :

// Call `find` with a given JWT
app.service('messages').find({
  authentication: {
    strategy: 'jwt',
    accessToken: 'someJWT'
  }
});

L'appelant (comme un transport REST ou websocket, un hook ou un test unitaire) sera responsable de la réussite de params.authentication . Cela signifie qu'il n'y aura plus de confusion si le crochet authenticate s'exécute pour les appels internes ou non ou d'où proviennent réellement les informations d'authentification.

Le crochet authenticate

Le crochet authenticate continuera d'exister. Il faudra une liste de noms de stratégie et sera soit

  • Passez au crochet suivant avec la première stratégie qui n'a pas généré d'erreur et fusionnez sa valeur de retour (voir ci-dessous) en params
  • Ou lancer l'erreur de la première stratégie qui a échoué si toutes les stratégies ont échoué

    Si params.authentication contient un nom strategy seule cette stratégie sera appelée. Sinon, toutes les stratégies seront appelées. Si params.authentication n'est pas du tout défini, le hook

  • Lancer une erreur pour les appels externes

  • Continuez comme d'habitude pour les appels internes (par exemple lors de la configuration manuelle de params.user )
app.service('messages').hooks({
  before: authenticate('jwt', 'local', 'anonymous')
});

Stratégies d'authentification

Une stratégie d'authentification de base est un objet avec une méthode authenticate qui obtient les données de params.authentication et renvoie un objet de réussite ou renvoie une erreur en cas d'échec :

const { Forbidden } = require('@feathersjs/errors');

const daveStrategy = {
  async authenticate (authParams) {
    const { username, password } = authParams;

    if (username === 'david' && password === 'secret') {
      return {
        user: {
          name: 'Dave',
          admin: true
        }
      };
    }

    throw new Forbidden('Not super Dave');
  }
};

app.authentication.registerStrategy('superdave', daveStrategy);

Dans le hook authenticate , l'objet renvoyé sera fusionné dans l'appel de service params donc cet exemple définira params.user .

Stratégies d'extension

Les stratégies d'authentification peuvent contenir et appeler des méthodes supplémentaires en interne. Les stratégies Feathers seront implémentées sous forme de classes pouvant être personnalisées par extension (cela remplacera les vérificateurs et combinera essentiellement la stratégie et le vérificateur en une seule classe) :

class LocalStrategy {
  constructor(app);
  async findUser(authParams);
  async comparePassword(user, password);
  async authenticate (authParams);
}

class MyLocalStrategy extends LocalStrategy {
  async findUser(authParams);
}

app.authentication.registerStrategy('local', new MyLocalStrategy(app));

analyse HTTP

Une stratégie peut également fournir une méthode parse qui obtiendra une requête et une réponse HTTP Node de base et devrait renvoyer la valeur pour params.authentication (ou null ):

const daveStrategy = {
  async authenticate (authParams) {
    throw new Forbidden('Not super Dave');
  }

  async parse (req, res) {
    const apiKey = req.headers['x-super-dave'];

    if (apiKey) {
      return {
        strategy: 'superdave',
        apiKey
      }
    }

    return null;
  }
};

Les bibliothèques HTTP peuvent alors décider si et comment elles utilisent ces méthodes pour définir params.authentication ou authentifier leur propre middleware.

app.authentifier

app.authenticate(authParams, [ strategies ]) exécutera les stratégies données avec les paramètres d'authentification donnés :

// Will return the user for a JWT (on the server)
const { user } = app.authenticate({ accessToken }, 'jwt');

la définition de params.authentication dans un appel de service sera le _seul_ moyen de fournir des informations d'authentification.

Pourriez-vous expliquer pourquoi il était nécessaire de fournir accessToken à chaque appel de service() ?

Cela ne s'applique qu'au serveur et c'est ce qui se passe déjà implicitement via params.provider et params.headers (dans le cas des websockets, ce ne sont que de faux en-têtes) qui sont définis pour chaque appel de service une fois l'authentification configurée. Cela brisait la séparation de Feathers entre les crochets et services indépendants du protocole de transport et le mécanisme de transport réel (comme HTTP avec Express ou Socket.io) et le rendait vraiment déroutant quand, par exemple, un crochet authenticate('jwt') s'exécute réellement et à quoi il sert ses informations d'authentification.

En ce qui concerne la convivialité, rien ne changera vraiment pour les appels externes ou internes, mais si vous souhaitez maintenant déclencher le hook authenticate explicitement sur le serveur, vous pouvez toujours définir params.authentication . Ceci est particulièrement important pour les nouveaux plugins de framework autres qu'Express (par exemple, Koa, HTTP2 ou une file d'attente de messagerie) qui ont désormais un moyen standardisé de transmettre leurs informations d'authentification au mécanisme d'authentification Feathers.

Le client d'authentification fera toujours des demandes authentifiées une fois connecté en appelant app.authenticate() .

Merci de clarifier. Très impatient de tester avec la v3, en particulier avec les clients natifs socket.io React.

Je mettrai certainement les informations sur les avant-premières ici. Il suffit de terminer le client d'authentification qui devrait gérer les Websockets authentifiés de manière beaucoup plus fiable. Une fois cela fait, ce serait formidable d'avoir de l'aide pour tester le nouveau noyau + l'authentification locale et jwt. oAuth devrait bientôt suivre.

quand sortira la version 3 ?

Une réponse à ma question ?

Vous pouvez voir les progrès actuels dans la branche principale et je publierai un article de blog lorsque les bêta-testeurs pourront l'essayer. Le statut est :

| Module | Code | Documents | CLI
| --- |:---:|:---:|---:|
| @feathersjs/authentification | | 100% | |
| @feathersjs/authentification-local | | 80% | |
| @featherjs/authentification-oauth | | 90%| |
| @feathersjs/authentication-client | | 80%| |

Salut, c'est super !

La flexibilité future est cool, mais je n'ai pas encore confiance en l'authentification dans mon projet FeathersJS et je traverse un processus déroutant pour créer cela.

Avoir une implémentation d'authentification complète, testée et sécurisée signifie que je peux passer en toute confiance aux fonctionnalités. L'une des meilleures raisons d'utiliser MeteorJS était son excellente intégration des comptes jusqu'au client.

En parcourant les problèmes de FeatherJS, beaucoup concernent l'authentification, je suis donc ravi que ce travail atterrisse !

Où se trouve la meilleure documentation (ou implémentation de référence) pour un système d'authentification sécurisé complet (authentification locale, contrôle d'accès, e-mails, etc.) dans FeathersJS aujourd'hui ?

C'est ce que j'ai jusqu'à présent - y a-t-il quelque chose de mieux?

2018/02 - Configuration de la vérification des e-mails dans FeathersJS (révision de l'article 2017)
2018/02 - Repo de l'article ci-dessus
2017/01 - Comment configurer la vérification des e-mails dans FeathersJS (cassé)
06/2018 - Authentification Vue avec Feathersjs

Merci d'avance!

Tous les problèmes liés ont été résolus et la pré-version de Feathers v4 avec toutes les modifications proposées mises en œuvre est disponible pour test. Consultez le guide de migration pour plus d'informations.

Cette page vous a été utile?
0 / 5 - 0 notes