【发布时间】:2018-04-09 08:55:06
【问题描述】:
这是我第一个使用护照的项目,总的来说我是 Node 新手。在使用 Chai 运行集成测试时,我无法将端点识别为授权。端点是 通过使用护照和 jsonwebtoken 库的令牌身份验证进行保护。以下是导入到测试中的其他文件;
const chai = require('chai');
const chaiHttp = require('chai-http');
const mongoose = require('mongoose');
const should = chai.should();
const { Session } = require('../models/practiceSession' );
const {User} = require('../models/user');
const { app, runServer, closeServer } = require('../app');
const { TEST_DATABASE_URL } = require('../config/mainConfig');
const {secret} = require('../config/mainConfig');
const jwt = require('jsonwebtoken');
chai.use( chaiHttp );
这里是端点的测试;
//test the session endpoints
it( 'should return a session with proper request', function(){
const user = new User({
name: 'random2',
email: 'random2@random.com',
password: 'Password2'
});
user.save( (err) => {
if (err){
console.log( err.message);
}
});
const token = jwt.sign({
id: user._id,
userName: user.name,
level: 0
}, secret, {
expiresIn: 60 * 60
});
console.log( "user id: ", user._id);
console.log( 'token is: ', token );
const practiceRequest = {
operation: "+",
number: "10", ///this will possible need to be sent as a number
min: "1",
max: "200"
};
return chai.request(app)
.post('/api/session')
.set('Authorization', 'Bearer ' + token)
.send( practiceRequest )
.then( (res) => {
res.should.have.status(201);
})
});
});
两个console.log 语句确认正在创建用户并具有_id 属性,并且正在创建一个有效的令牌 已创建(已在 jwt.io 上确认)。
这是端点的代码;
router.route("/session")
.post(passport.authenticate('jwt', { session: false }), jsonParser, ( req, res ) => {
console.log( req );
let practiceSession = [];
for ( let i = 0; i < req.body.number; i++ ){
let firstTerm = generateTerm( req.body.min, req.body.max );
let secondTerm = generateTerm( req.body.min, req.body.max );
const problem = {
operator: req.body.operation,
firstTerm,
secondTerm,
problem: `${ firstTerm } ${ req.body.operation } ${ secondTerm }`,
correctResponse: generateCorrectResponse( firstTerm, secondTerm, req.body.operation )
};
practiceSession.push( problem );
}
// save session into db sessions collection for use in the training-logic.js
Session
.create( {
userId: req.user._id,
problems: practiceSession
} )
.then(
session => res.status( 201 ).json( session) )
.catch( err => {
console.error( err );
res.status( 500 ).json( { message: 'Internal Server Error' } );
});
} );
此端点的测试失败,返回 401 响应和简单的Error: Unauthorized 这不是很多信息
而且我不知道在哪里继续排除故障。我的理解是,这意味着最初的passport.authenticate
即使在 jwt.io 站点上已确认它是有效的,端点处的令牌也不会识别为有效。有没有
生成令牌时我应该包括的其他信息?如果有怎么办?
我看过其他几个使用护照的例子; one, two, three 但我做到了 看不到如何将这些见解应用到我的实现中。
对此的任何帮助将不胜感激。感谢您的时间。
更新:
基于有效令牌正在到达端点但仍未被接受的事实,我尝试使用对用户身份验证端点的初始调用构建一个承诺链,然后使用从那里派生的令牌来测试会话生成端点。这就是努力;
it( 'should return a session with proper request', function(){
let token;
return chai.request(app)
.post('/api/user/authenticate')
.send( {
email: 'random@random.com',
password: 'password2'
} )
.then( (res) => {
res.should.have.status(200);
res.should.be.json;
console.log( res.body );
token = res.body.token;
return token;
})
.catch( (err) => {
console.log( 'failed at user authentication' );
})
.then( ( err, data ) => {
console.log( 'token value is ', token );
chai.request( app )
.post( '/api/session' )
.set( 'Authorization', `${ token }` )
.send( {
operation: "+",
number: "10",
min: "1",
max: "200"
})
.then( res => {
console.log( 'second response is ', res );
res.should.have.status(201);
} )
.catch( err => {
console.log( 'second promise ', err.message );
})
})
});
它仍然被拒绝为Unauthorized。从测试发送到会话端点的请求中缺少某些内容。会话端点中的console.log( req ) 确认它正在接收一个添加了大量信息的对象,与测试中从承诺链发送的信息相比。我不得不在外部范围内使用 token 变量来传递 chai.request(app) 命令之间的值。这与工作应用程序中存在的数据流不同。我不确定如何测试它;我的理解是,到目前为止我所尝试的并没有为端点提供足够的数据来验证请求。
任何帮助将不胜感激。感谢您的时间。
【问题讨论】:
-
Debug 验证调用。
-
James,感谢您的参考,我从未在 Node.js 的服务器端使用过 Chrome 调试器。在应用程序的正常运行中,我在 sessionRouter 端点(上图)中设置了一个断点并检查了请求对象。在标题中有一个
authorization: "Bearer eyJhbGciOiJIUzI1NiIsIn..."的属性我的理解是这是在测试中发送的。这个工具提供了额外的信息,但我认为它证实了我一直在做的事情。我仍然不确定为什么测试因“未经授权”而失败。再次感谢您的宝贵时间。 -
听起来令牌标头正在上升(这很好)。将您的问题缩小到您的 JWT 无效:)
标签: node.js authentication integration-testing chai passport.js