2017-05-25 87 views
0

我是一个使用feathersjs的新手,它非常灵活,对于简单的CRUD用例似乎非常高效。我一直在试图自定义羽毛的授权问题。这里显示了用于定制登录响应的文档中的示例。feathersjs授权定制问题

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

按预期工作,收到的JSON具有访问令牌和foo属性。不过,如果我修改了它添加一个钩子函数是这样的:

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

或只是

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

或将其设置在面前,也没关系,新属性没有设置。登录钩代码:

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'); 
    }); 
    }; 
}; 

此代码运行时,在数据库中创建的会话,都好,但创建,并在控制台中显示的新标记之前的响应去到客户端。 foo在那里,但不是在hook.result对象中添加新的标记属性。区别在于foo是同步添加的,令牌属性是异步设置的。我读了这个答案(Understanding FeathersJS hooks),但对于使用羽毛生成的代码我不知道该怎么做,如果它适用于Auk(我使用的羽毛版本)。现在我的问题:

  1. 如何在发送异步时发送令牌属性?
  2. 如何更改/覆盖有效载荷,密码和令牌的选项。实际上,这个秘密将按会话进行,而不是像配置中那样独特或全系统。系统范围 - 如果令牌使用RSA加密,则可能会将其设置为公钥。
  3. 如果资源是由REST服务器自己计算的,那么如何创建自定义服务(而不是基于sequelize,内存或其他后端)的示例?在文档的高级部分中举个例子会很好。

谢谢,抱歉,如果答案很明显,但我没有达到哈哈!作为第三个问题和第一个问题的关键时刻是feathersjs。

回答

0

终于我能做到了,我也回答了我前几天发表的另一篇文章。

我创建了一个叫做会话其他服务和服务创建代码里面我把这个:

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'); 
    }); 
    } 
}); 

由于sequelize查询的异步特性和createJWT功能,响应总是不管我在创作集返回。所以,我意识到要返回每个嵌套的承诺(线索来自createJWT在身份验证示例中返回的示例),但是我被这个续集所困惑。最后是一个处理羽毛承诺的新手错误。有了这个答案,我的other post也被回答了。

谢谢。