首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >无模式服务不返回预期的JSON对象

无模式服务不返回预期的JSON对象
EN

Stack Overflow用户
提问于 2017-05-24 00:15:24
回答 1查看 1.1K关注 0票数 0

有人能解释一下服务创建是如何工作的吗?许多小时后,我在接收JSON对象时碰到了一个墙,而不是我所期望的那样;我附带了这个前钩子的代码,它至少给了我一个JSON对象,而不是前面那个对象的404错误。但是,正如我前面描述的,我在服务创建函数中放入的任何内容都会被返回,不管在操作数据之前或之后是什么钩子。

服务代码现在是这样的:

代码语言:javascript
复制
module.exports = function () {
  const app = this;

  // Initialize our service with any options it requires
  app.use('/v1/login',{
    create(data, params){
      console.log("creating service");
      return Promise.resolve(data); // data or params or whatever is returned to the REST ignoring any modification done via hooks
    }
  });

  // Get our initialized service so that we can register hooks and filters
  const service = app.service('/v1/login');

  service.hooks(hooks);

  if (service.filter) {
    service.filter(filters);
  }
};

钩子文件是相同的,后置钩子(登录)现在如下:

代码语言:javascript
复制
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) {
    if (hook.type !== 'before') {
      throw new errors.Unprocessable('This hook should only be used as before hook.');
    }
    const sequelizeClient = hook.app.get('sequelizeClient');
    sequelizeClient.query('SELECT to_jsonb(login_user($app::varchar, $usr::varchar, $pwd::varchar)) resultcode',
      { bind: { app: hook.data.app, usr: hook.data.usr, pwd: hook.data.pwd },
        type: sequelizeClient.QueryTypes.SELECT }
    ).then(login => {
      if (login[0].resultcode.loginStatus !== 0){
        throw new errors.NotAuthenticated(login[0].resultcode.message);
      }else if(login[0].resultcode.sessionId !== null){
        delete hook.data.usr;
        delete hook.data.pwd;
        hook.data.resultcode = login[0].resultcode;
        var payload = { 'iss': 'feathers',
          'sub': hook.data.resultcode.sessionId,
          'aud': 'localhost',
          'rol': hook.data.resultcode.rol,
          'nbf': moment(),
          'iet': moment(),
          'jti': hook.data.resultcode.nonce
        };
        var opts = {
          name: 'jwt',
          entity: 'sessions',
          service: 'sessions',
          passReqToCallback: true,              
          session: false
        };
        opts.jwtFromRequest = [ExtractJwt.fromAuthHeader(),
          ExtractJwt.fromAuthHeaderWithScheme('Bearer'),
          ExtractJwt.fromBodyField('body')
        ];
        opts.secret = hook.data.resultcode.message;
        hook.app.passport.createJWT(payload, opts)
        .then( jwtResult => {
          hook.result = { "token": jwtResult };
          return hook;
        })
        .catch(error => {
          console.log("JWT-ERROR: "+error);
          throw new errors.GeneralError('Error generating jwt. Login failed');
        });
      }else{
        console.log("ERROR: No session created");
        throw new errors.GeneralError('Session cannot be created');
      }
    }).catch(error => {
      console.log("ERROR: "+error);
      throw new errors.GeneralError('Database error');
    });
  };
};

正如我所说,返回的是在服务创建方法中接收到的params。是否有一种方法可以消除服务创建的第二个param?,我试过了,但是在其他方面,出现了一个期望中间件函数的错误。我做错了什么,或者我误解了钩子(我认为它们在返回给REST客户端之前操纵数据和参数,但似乎并非如此。请解释一下。我是新用羽毛的。我期望实现在第161页所写的“专业提示: hook.result也可以设置在一个预挂钩,它将跳过服务方法调用(但运行所有其他钩子)。”,但没有运气到现在。还有其他我错过的方式或条件吗?

更新,还没有进展,

我看到了身份验证服务代码,并尝试执行类似的操作,它们实际上返回了创建令牌的JWT承诺,并在JSON中返回令牌,因此我将所有进程都放在服务创建中(不管有没有钩子,都不会返回任何返回的结果)。

代码语言:javascript
复制
const errors = require('feathers-errors');
const jwt = require('feathers-authentication-jwt');
const ExtractJwt = require('passport-jwt').ExtractJwt;
const moment = require('moment');

const hooks = require('./login.hooks'); //optional the only hook on create is to validate that params user and password are present
const filters = require('./login.filters');

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

  // Initialize our service with any options it requires
  app.use('/v1/login',{
    create(data, params){
      console.log("creating service");
      const sequelizeClient = app.get('sequelizeClient');
      var modelSession = sequelizeClient.query('SELECT to_jsonb(login_user($app::varchar, $usr::varchar, $pwd::varchar)) resultcode',
        { bind: { app: data.app, usr: data.usr, pwd: data.pwd, cte: params.headers },
          type: sequelizeClient.QueryTypes.SELECT }
      ).then(login => {
        if (login[0].resultcode.login_status !== 0){
          throw new errors.NotAuthenticated(login[0].resultcode.pmessage);
        }else if(login[0].resultcode.sessionId !== null){
          delete data.usr;
          delete data.pwd;
          data.resultcode = login[0].resultcode;
          var payload = { 'iss': 'feathers',
            'sub': data.resultcode.sessionId,
            'aud': 'localhost',
            'rol': data.resultcode.rol,
            'nbf': moment(),
            'iet': moment(),
            'jti': data.resultcode.nonce
          };
          var opts = {
            name: 'jwt',
            entity: 'sessions',
            service: 'sessions',
            passReqToCallback: false, // to avoid verification                
            session: false
          };
          opts.jwtFromRequest = [ExtractJwt.fromAuthHeader(),
            ExtractJwt.fromAuthHeaderWithScheme('Bearer'),
            ExtractJwt.fromBodyField('body')
          ];
          opts.secret = 'secret';
          return app.passport.createJWT(pload, opts)
          .then( function(jwtResult) { // mimic of authentication service, but less sophisticated
            delete data.resultcode;
            return { token: jwtResult }; // expected result, but nothing is received
          })
          .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');
      });
    }
  });

  // Get our initialized service so that we can register hooks and filters
  const service = app.service('/v1/login');

  service.hooks(hooks); //This line can be commented out

  if (service.filter) {
    service.filter(filters);
  }
};

钩子是这个

代码语言:javascript
复制
module.exports = {
  before: {
    all: [],
    find: [ disallow() ],
    get: [ disallow() ],
    create: [ validateLoginParams() ], // just to see if the params are truthy
    update: [ disallow(), disableMultiItemChange() ],
    patch: [ disallow(), disableMultiItemChange() ],
    remove: [ disallow(), disableMultiItemChange() ]
  },
...  //All is as in default, so empty brackets ;-)
}

该项目是使用羽毛-cli和羽毛Auk创建的,这是与json相关的包。

代码语言:javascript
复制
  "dependencies": {
    "body-parser": "^1.17.2",
    "compression": "^1.6.2",
    "cors": "^2.8.3",
    "feathers": "^2.1.2",
    "feathers-authentication": "^1.2.3",
    "feathers-authentication-hooks": "^0.1.3",
    "feathers-authentication-jwt": "^0.3.1",
    "feathers-authentication-local": "^0.3.4",
    "feathers-authentication-oauth2": "^0.2.4",
    "feathers-configuration": "^0.4.1",
    "feathers-errors": "^2.8.0",
    "feathers-hooks": "^2.0.1",
    "feathers-hooks-common": "^3.3.2",
    "feathers-rest": "^1.7.2",
    "feathers-sequelize": "^2.0.0",
    "feathers-socketio": "^1.6.0",
    "helmet": "^3.6.0", ...

为了启动一个新项目,我使用了两/三周的JavaScript框架,我希望看到它在未来的版本中使用TypeScript (对我来说代码要清晰得多)。我希望很快就能找到解决这个问题的办法,或者有人能指出我犯了什么错误,或者如果我确实不知道如何使用羽毛,也不知道自己的意图是什么。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-05-25 22:58:58

在仔细了解了羽毛中的身份验证代码以及其他服务是如何使用sequelize创建的之后,我从一开始就意识到问题在于尝试在不使用任何模型的情况下执行新服务。我读过这两个谷歌页面-- https://github.com/feathersjs/feathers-hooks/issues/25https://github.com/feathersjs/feathers/issues/351,但是提到的解决方案都会导致一个不存在的页面。真正的问题是如何进行无模式服务,或者如何创建返回任何后端中不存在的资源的服务;换句话说,如何返回通过服务本身生成的资源。

答:不可能,除非你从头开始创建一个服务。我说过,我唯一的方法是使用内置的身份验证服务,但是如果您需要做其他非模式的事情(不是身份验证,而是电子邮件注册,或者是在服务中或直接从数据库中完成的进程的结果,但是没有CRUD),那么您就必须请求羽feathersjs的开发人员(请帮助,我很快需要其他非CRUD服务)。

最后,我只是消除了默认挂钩,更改的身份验证服务代码如下:

代码语言:javascript
复制
  // to create a new valid JWT (e.g. local or oauth2)
  app.service('/v1/authentication').hooks({
    before: {
      create: [
        // authentication.hooks.authenticate(config.strategies),
        validateLoginParams(),
        login()
      ],
      remove: [
        authentication.hooks.authenticate('jwt')

..。

登录钩子是整个代码,它返回带有结果的钩子,我得到访问令牌JSON。现在,我的问题是生成的令牌没有我设置的有效负载,而只有那些在身份验证配置中不存在的部分。

感谢您的时间和耐心阅读这个代码故事。希望这能对其他新手有所帮助。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/44146972

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档