Express中express.static配合身份验证中间件不生效如何解决?
问题成因
核心问题是Express中间件和路由的执行顺序冲突:
- Express的中间件、路由是按照代码编写的顺序依次匹配执行的,你原先的写法将带
ensureLoggedIn身份校验的静态资源中间件挂载在了Facebook登录、回调路由的前面。 - 所有根路径下的请求(包括
/auth/facebook、/facebook/callback)都会先触发身份校验,此时用户尚未完成登录,会被直接302跳转到登录页,陷入无限重定向的死循环,自然无法完成登录流程、加载静态资源。 - 你手动为每个静态资源声明单独路由时,这些路由是写在登录相关路由之后的,登录请求不会被后面的身份校验拦截,因此可以正常完成登录流程。
正确实现方案
方案1:调整路由和中间件的挂载顺序(最简单)
把不需要身份校验的登录、回调路由放在静态资源中间件前面即可:
// 先定义无需登录校验的路由 app.get('/auth/facebook', passport.authenticate('facebook', { scope:'email' })) app.get('/facebook/callback', passport.authenticate('facebook', { successRedirect : '/', failureRedirect : '/auth/facebook' })) // 再挂载带身份校验的静态资源中间件 app.use('/', ensureLoggedIn('/auth/facebook'), express.static(__dirname + '/public'))
该方案无需修改前端资源引用路径,改完即可正常运行。
方案2:为静态资源增加统一路由前缀
如果不想改动路由顺序,可以给静态资源单独分配前缀,避免和业务路由冲突:
- 调整静态资源挂载逻辑:
// 静态资源统一走/static前缀 app.use('/static', ensureLoggedIn('/auth/facebook'), express.static(__dirname + '/public')) // 根路径单独返回入口html app.get('/', ensureLoggedIn('/auth/facebook'), (req, res) => { res.sendFile(__dirname + '/public/index.html') })
- 修正
index.html中的资源引用路径:
<script src="/static/script-a.js"></script> <script src="/static/scripts/script-b.js"></script>
额外注意事项
你当前index.html中的script标签属性存在笔误,正确属性名是src不是scr,该问题也会导致脚本加载失败,记得同步修正。
内容的提问来源于stack exchange,提问作者user2272048
相关产品推荐
相关产品推荐

