2017-05-25 5 views
0

Je suis un débutant en utilisant feathersjs, et il est très flexible et semblait être très productif pour les cas d'utilisation simple CRUD. J'ai eu des problèmes en essayant de personnaliser l'autorisation des plumes. L'exemple dans la documentation pour personnaliser la réponse de connexion s'affiche ici. Fonctionne comme prévu, le JSON reçu a le jeton d'accès et la propriété foo. Cependant, si je l'ai modifié en ajoutant une fonction de crochet comme ceci:feathersjs autorisation personnalisation problème

app.service('/authentication').hooks({ 
    after: { 
    create: [ 
     hook => { 
     hook.result.foo = 'bar'; 
     }, 
     login() 
    ] 
    } 
}); 

ou tout simplement

after:{ 
    create: [ 
    login() 
    ] ... 

ou le mettre en avant, peu importe la nouvelle propriété est pas définie. le code de crochet de connexion est:

const errors = require('feathers-errors'); 
const jwt = require('feathers-authentication-jwt'); 
const ExtractJwt = require('passport-jwt').ExtractJwt; 
const moment = require('moment'); 

module.exports = function() { 
    return function (hook) { 
    // call a function that validates the username and password and returns a session id, rol and other information to fillout the payload 
    const sequelizeClient = hook.app.get('sequelizeClient'); 
    sequelizeClient.query('SELECT ...) // Sequelize magic 
    .then(mySession => { // session successfully created 
     hook.data.resultcode = mySession[0].resultcode; 
     delete hook.data.usr; 
     delete hook.data.pwd; 
     //payload I want, but simply doesn't go or is partially taken 
     var pload = { header: { typ: 'access' }, 
      strategy: 'jwt', 
      'issuer': 'feathers', 
      'subject': hook.data.resultcode.session_id, 
      'audience': 'localhost', 
      'rol': hook.data.resultcode.rol, 
      'nbf': moment(), 
      'iet': moment() 
     }; 
     var opts = { 
      name: 'jwt', 
      entity: 'sessions', 
      service: 'sessions', 
      passReqToCallback: false, 
      session: false // whether to use sessions, 
      //Verifier: Verifier 
     }; 
     opts.jwtFromRequest = [ExtractJwt.fromAuthHeader(), 
      ExtractJwt.fromAuthHeaderWithScheme('Bearer'), 
      ExtractJwt.fromBodyField('body') 
     ]; 
     opts.secret = 'secret'; 
     hook.data.payload = pload; // as documentation says to modify the payload, but does not work 
     hook.params.payload = pload; 
     hook.app.passport.createJWT(pload, opts) 
     .then(jwtResult => { 
      hook.result.token = jwtResult; 
      console.log("after hook result:"+ JSON.stringify(hook.result)); 
      return hook; 
     }) 
     .catch(error => { 
      console.log("JWT-ERROR: "+error); 
      throw new errors.GeneralError('Error generating jwt. Login failed'); 
     }); 
    }).catch(error => { 
     console.log("ERROR: "+error); 
     throw new errors.GeneralError('Database error'); 
    }); 
    }; 
}; 

Ce code est exécuté, la session est créé dans la base de données, tout bon, mais la réponse va au client avant que le nouveau jeton est créé et affiché dans la console. le foo est là, mais pas la nouvelle propriété de jeton ajoutée dans l'objet hook.result. La différence est que foo est ajouté de manière synchrone, la propriété token est définie de manière asynchrone. J'ai lu cette réponse (Understanding FeathersJS hooks), mais pour un le code généré avec plumes-cli je ne comprends pas comment le faire, et si elle s'applique pour Auk (la version de plumes que j'utilise.) Maintenant mes questions:

  1. Comment puis-je envoyer la propriété de jeton lorsqu'elle est générée de manière asynchrone?
  2. Comment puis-je modifier/remplacer la charge utile, le secret et les options du jeton. Le secret sera en fait par session, pas unique ou à l'échelle du système comme dans la configuration. Le système wide-one va peut-être être défini comme une clé publique si le jeton est chiffré à l'aide de RSA par exemple.
  3. Où est un exemple de création d'un service personnalisé (non basé sur sequelize, de la mémoire ou autre backend) si la ressource est calculée par le serveur REST lui-même? Serait bon d'avoir un exemple dans la section avancée des docs.

Merci, et désolé si la réponse est évidente, mais je n'ai pas atteint le aha! moment avec feathersjs pour les cas comme la troisième et première question concerne.

Répondre

0

enfin je pourrais le faire et je réponds aussi à un autre post que j'ai publié il y a quelques jours.

J'ai créé un autre service appelé session et dans le code de création de services dirais-je:

module.exports = function() { 
const app = this; 

// Initialize our service with any options it requires 
app.use('/v1/session', { 
    create(data, params){ 
    console.log("creating service"); 
    const sequelizeClient = app.get('sequelizeClient'); 
    return sequelizeClient.query('SELECT ... //Sequelize magic must be returned its promise 
    ).then(login => { 
     delete data.usr; 
     delete data.pwd; 
     data.resultcode = login[0].resultcode; 
     var payload = { 'iss': 'feathers', 
      'sub': data.resultcode.session_id, 
      'aud': 'localhost', 
      'nbf': moment(), 
      'iet': moment() 
     }; 
     var opts = { 
      name: 'jwt', 
      entity: 'sessions', 
      service: 'sessions', 
      passReqToCallback: false, 
      session: false 
     }; 
     opts.jwtFromRequest = [ExtractJwt.fromAuthHeader(), 
      ExtractJwt.fromAuthHeaderWithScheme('Bearer'), 
      ExtractJwt.fromBodyField('body') 
     ]; 
     opts.secret = 'secret'; 
     return app.passport.createJWT(pload, opts) // Here is the correction return the nested promise 
     .then(function(jwtResult) { 
      delete data.resultcode; 
      data.token = jwtResult; 
      return Promise.resolve(data); // and return a promise with the desired result, which can be any object, not necessarily data or params 
     }) 
     .catch(error => { 
      console.log("JWT-ERROR: "+error); 
      throw new errors.GeneralError('Error generating jwt. Login failed'); 
     }); 
     } 
    }).catch(error => { 
     console.log("ERROR: "+error); 
     throw new errors.GeneralError('Database error'); 
    }); 
    } 
}); 

En raison de la nature asynchrone de requête sequelize et les fonctions de createJWT, la réponse a toujours été ce que je mis dans la création revenir. Ainsi, j'ai réalisé pour retourner chaque promesse imbriquée (l'indice est venu d'un exemple où le createJWT est retourné dans un exemple d'authentification), mais j'ai été confondu par le sequelize. À la fin était une erreur de débutant manipulant des promesses dans les plumes. Avec cette réponse, mon other post a également été répondu.

Merci.