我是使用feathersjs的新手,它非常灵活,对于简单的CRUD用例来说似乎非常高效。我一直在尝试定制羽毛的授权问题。自定义登录响应的文档中的示例显示在此处。
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对象中添加新的token属性。区别在于foo是同步添加的,token属性是异步设置的。我读了这个答案(Understanding FeathersJS hooks),但是对于使用feat-cli生成的代码,我不知道怎么做,如果它适用于Auk(我正在使用的羽毛版本)。现在我的问题:
谢谢,对不起,如果答案很明显,但我还没有达到啊哈!第三个问题和第一个问题是关于案例的羽毛问题。
答案 0 :(得分:0)
最后我能做到,我还回答了几天前发表的另一篇文章。
我创建了另一个名为session的服务,在服务创建代码中我把它放在:
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函数的异步性质,响应始终是我在创建返回中设置的。因此,我意识到返回每个嵌套的promise(线索来自一个在身份验证示例中返回createJWT的示例),但我对sequelize的一个感到困惑。最后是处理羽毛承诺的新手错误。有了这个答案,我的other post也得到了答复。
感谢。