使用koa.js和koa-passport,我可以有条件地应用中间件吗?
我的服务器使用koa-passport和内置的'会话来验证网络访问者。认证
app.use( passport.initialize() );
app.use( passport.authenticate( 'session', {} ); // = app.use( passport.session() );
现在我需要通过SSL端口访问服务器作为API端点。 API端点不使用会话;验证是通过承载令牌进行的。 Passport-http-bearer就是这样做的:
app.use( passport.initialize() );
app.use( passport.authenticate( 'session', {} );
app.use( passport.authenticate( 'bearer', {session:false} ));
当然,这不起作用,因为任何一个会议'或者“持票人”#39;将永远失败,所以没有请求通过。
我想过有条件地应用中间件:
if( this.request.headers.authenticate.startsWith( 'Bearer' )){
app.use( passport.authenticate( 'bearer', {session:false} ));
} else {
app.use( passport.authenticate( 'session', {} );
}
当然,这不起作用,因为堆栈不是在运行时为每个请求构建的,因此请求标头是未定义的,并且不会编译。
我试过koa-除非;理论上它应该可行,但即使是示例代码也会在koa@1.2上引发错误。
所以目前我已将条件修补为护照-htt-bearer策略;这很有效,但它几乎无法支持。
有什么想法吗?谢谢!
答案 0 :(得分:0)
我个人之前没有使用过承载者,但您应该能够使用上下文中提供的isAuthenticated帮助器方法。
这是另一个stackoverflow线程Documentation for "ensureAuthentication" "isAuthenticated" passport's functions?
exports.isAuthenticated = async (ctx, next) => {
if (ctx.isAuthenticated()) {
await next()
}
if (!ctx.isAuthenticated()) {
ctx.session.returnTo = ctx.request.originalUrl
ctx.redirect('/auth/login')
}
}
如果这不起作用,您可以创建自定义中间件来处理这两种情况。 Passport.js optional authentication
exports.isAuthenticated = async (ctx, next) => {
if (ctx.isAuthenticated() || await passport.authenticate('bearer', {session: 'false'} ) ) {
await next()
}
ctx.session.returnTo = ctx.request.originalUrl
ctx.redirect('/auth/login')
}
答案 1 :(得分:0)
不确定是否适用,但您可以通过这样做三元来做有条件的中间件
koa.use(koa.context.something ? (ctx, next) => next() : passport.initialize())
所以在你的情况下,这应该工作
app.use(this.request.headers.authenticate.startsWith('Bearer') ?
passport.authenticate('bearer', {session:false}))
: passport.authenticate('session', {})
)