Passport JWT auth in unit test - socket挂断

时间:2016-12-30 15:11:17

标签: javascript node.js unit-testing passport.js jwt

我有一段情绪化的时间试图使用护照的JWT策略测试受保护的路线,并使用授权标题。

我已经尝试过axios,supertest,superagent,我也得到同样的错误 - ' socket挂断':

Error: socket hang up
at createHangUpError (_http_client.js:253:15)
at Socket.socketOnEnd (_http_client.js:345:23)
at emitNone (events.js:91:20)
at Socket.emit (events.js:185:7)
at endReadableNT (_stream_readable.js:974:12)
at _combinedTickCallback (internal/process/next_tick.js:74:11)
at process._tickDomainCallback (internal/process/next_tick.js:122:9) code: 'ECONNRESET', response: undefined }

这在开发环境中非常有效,这只发生在测试环境中 - 单元测试或dev env指向测试数据库/用户。

我知道这个错误意味着连接因服务器崩溃或语法错误而关闭,但是没有语法错误。端点没有通过护照身份验证:

passport.authenticate('jwt'...

为什么呢?怎么解决这个问题?

终点:

router.route('/private')
  .get(
    passport.authenticate('jwt', { session: false }), (req, res, next) => {
      res.json({ allTheThings: true });
  })

测试:

describe('GET /api/private', () => {
  it('should work', () => {
    const USER_JWT_VALID = 'JWT asdf.....';

    let instance = axios.create();
    instance.defaults.headers.common['Authorization'] = USER_JWT_VALID;

    return instance.get('http://localhost:3000/api/private')
      .then((response) => {
        expect(response.data).to.be.an('object'); // response.data undefined
      }).catch((error) => {
        console.log('err ', error); //socket hang up
      });
  });
});

如果我删除passport.authenticate并只是发送一个json响应,它会按预期工作。

日志显示请求与Authorization标头中的正确JWT一起发送。

RE评论

我有一个不同的开发和测试用户/用户。使用dev中的测试数据库,我能够复制单元测试中出现的问题。如果我排除授权标题,正如预期的那样,我会得到一个未经授权的#39;响应(来自令牌检查功能)。

一旦我向JWT添加授权标题,我就不会得到任何回复:(

进一步调试

在测试环境中,如果有授权标头,我的api似乎无法再执行任何GET请求。没有标题,一切正常。我怀疑这与最近的一些依赖更新有关。

1 个答案:

答案 0 :(得分:0)

为测试环境创建一个全新的用户并在单元测试中使用它之后,一切都按预期工作。使用授权标头中的用户JWT的GET请求可以完美地工作。

似乎在测试环境(来自mongo db)中用于身份验证的用户以某种方式使用了无效的JWT。可能与基于用户架构构建JWT的方式有关。

我不知道为什么或如何发生这种情况(早期构建阶段)。现在无法复制。

我的单元测试正在执行以下操作:

1)POST到身份验证端点以获取JWT令牌(来自用户电子邮件和密码)

2)使用该JWT获取仅具有私有身份验证的端点。

在私人GET上,passport.authenticate('jwt' ....根本就没有工作,因此没有请求或回复。

除了无效的JWT之外,我看不出任何其他原因。

我从中了解到,如果您在进行身份验证时遇到失败的单元测试,请排除旧用户/新用户并从中进行操作。