如何提供带身份验证的静态文件?
How do I serve static files with authentication?
这是我的文件夹结构:
/app
server.js
/public
index.html
script-a.js
/scripts
script-b.js
这些是我index.html
的相关内容:
<!-- index.html -->
.....
...
<script scr="/script-a.js"></script>
<script scr="/script-b.js"></script>
这些是server.js
的相关内容:
import express from 'express'
import session from 'express-session'
import NedbStore from 'nedb'
import passport from 'passport'
import { Strategy as FacebookStrategy } from 'passport-facebook'
import { ensureLoggedIn } from 'connect-ensure-login'
....
..
const db = new NedbStore({ filename: `${__dirname}/db/nedb.db`, autoload: true })
const DB = dbAsyncWrapper(db)
app.use(cors({
origin: '*',
credentials: true,
optionSuccessStatus: 200
}))
app.use(function(req, res, next) {
res.header('Access-Control-Allow-Origin', 'http://localhost:4200')
res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept, Authorization')
res.header('Access-Control-Allow-Methods', 'POST, GET')
next()
})
app.use(cookieParser())
app.use(express.json({ limit: '50mb' }))
app.use(express.urlencoded({ extended: true, limit: '50mb' }))
app.use(session({
secret: 'googoogaga',
resave: false,
saveUninitialized: false
}))
app.use(passport.initialize())
app.use(passport.session())
passport.use(new FacebookStrategy({
clientID : FACEBOOK_APP_ID,
clientSecret : FACEBOOK_APP_SECRET,
callbackURL : "http://localhost:4200/facebook/callback",
profileFields : ['id']
}, async(accessToken, refreshToken, profile, done) => {
let facebookId = profile.id
let userInDb = await DB.getUser()
if (userInDb && userInDb.facebookId === facebookId) {
await DB.updateUser({ accessToken })
done(null, userInDb)
} else {
let newUser = await DB.updateUser({ facebookId, accessToken })
done(null, newUser)
}
}))
passport.serializeUser(function(user, done) {
done(null, user)
})
passport.deserializeUser(function(user, done) {
done(null, user)
})
app.use('/', ensureLoggedIn('/auth/facebook'), express.static(__dirname + '/public'))
app.get('/auth/facebook', passport.authenticate('facebook', { scope:'email' }))
app.get('/facebook/callback', passport.authenticate('facebook', {
successRedirect : '/',
failureRedirect : '/auth/facebook'
}))
使用上面的代码,我期望:
- 转到
/
- 被重定向到 facebook 进行登录
- 返回
/
- 已经
index.html
服务和加载
- 正确加载
script-a.js
和 script-b.js
实际情况是:
我转到 /
,我被重定向到 /auth/facebook
,状态代码为 302
。
如果我删除:
app.use('/', ensureLoggedIn('/auth/facebook'), express.static(__dirname + '/public'))
改为手动声明每个路由处理程序,一切正常:
....
..
app.get('/', ensureLoggedIn('/auth/facebook'), (req,res) => {
res.sendFile(__dirname + '/public/index.html')
})
app.get('/script-a.js', ensureLoggedIn('/auth/facebook'), (req,res) => {
res.sendFile(__dirname + '/public/script-a.js')
})
app.get('/script-b.js', ensureLoggedIn('/auth/facebook'), (req,res) => {
res.sendFile(__dirname + '/public/scripts/script-b.js')
})
如果你的授权是这样实现的:
app.use('/public', ensureLoggedIn('/auth/facebook'));
然后,您可以 运行 在您的 express.static()
路线之前:
app.use(ensureLoggedIn('/auth/facebook'));
app.use(express.static(__dirname + '/public'));
或者,您将其专门合并到静态路由中:
app.use(ensureLoggedIn('/auth/facebook'), express.static(__dirname + '/public'));
When I also include the first 2 lines, not even the index.html gets served. I only get a failed facebook redirect registered on the network panel.
然后,您的身份验证中间件要么正确地拒绝对未经授权的客户端的访问,要么您的身份验证中间件无法正常工作。您的问题中没有任何内容表明可能是或可以让我们为您诊断。
But all other static files fail to be served.
为了帮助您解决这个问题,我们必须查看未正确提供的静态文件的具体信息(URL 在网页中,资源在您的文件系统中的位置, ETC...)。为了使静态文件正常工作,人们会犯 4-5 个常见错误。最常见的只是在网页中使用错误的 URL 静态资源,例如图像,CSS 文件,脚本文件等...
不幸的是,我找到的唯一解决方案是将我的 /public
文件夹变成平面结构并执行:
app.get('/', ensureLoggedIn('/auth/facebook'), (req,res) => {
res.sendFile(__dirname + '/public/index.html')
})
app.get('/:filename', ensureLoggedIn('/auth/facebook'), (req,res) => {
res.sendFile(__dirname + `/public/${req.params.filename}`)
})
这是我的文件夹结构:
/app
server.js
/public
index.html
script-a.js
/scripts
script-b.js
这些是我index.html
的相关内容:
<!-- index.html -->
.....
...
<script scr="/script-a.js"></script>
<script scr="/script-b.js"></script>
这些是server.js
的相关内容:
import express from 'express'
import session from 'express-session'
import NedbStore from 'nedb'
import passport from 'passport'
import { Strategy as FacebookStrategy } from 'passport-facebook'
import { ensureLoggedIn } from 'connect-ensure-login'
....
..
const db = new NedbStore({ filename: `${__dirname}/db/nedb.db`, autoload: true })
const DB = dbAsyncWrapper(db)
app.use(cors({
origin: '*',
credentials: true,
optionSuccessStatus: 200
}))
app.use(function(req, res, next) {
res.header('Access-Control-Allow-Origin', 'http://localhost:4200')
res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept, Authorization')
res.header('Access-Control-Allow-Methods', 'POST, GET')
next()
})
app.use(cookieParser())
app.use(express.json({ limit: '50mb' }))
app.use(express.urlencoded({ extended: true, limit: '50mb' }))
app.use(session({
secret: 'googoogaga',
resave: false,
saveUninitialized: false
}))
app.use(passport.initialize())
app.use(passport.session())
passport.use(new FacebookStrategy({
clientID : FACEBOOK_APP_ID,
clientSecret : FACEBOOK_APP_SECRET,
callbackURL : "http://localhost:4200/facebook/callback",
profileFields : ['id']
}, async(accessToken, refreshToken, profile, done) => {
let facebookId = profile.id
let userInDb = await DB.getUser()
if (userInDb && userInDb.facebookId === facebookId) {
await DB.updateUser({ accessToken })
done(null, userInDb)
} else {
let newUser = await DB.updateUser({ facebookId, accessToken })
done(null, newUser)
}
}))
passport.serializeUser(function(user, done) {
done(null, user)
})
passport.deserializeUser(function(user, done) {
done(null, user)
})
app.use('/', ensureLoggedIn('/auth/facebook'), express.static(__dirname + '/public'))
app.get('/auth/facebook', passport.authenticate('facebook', { scope:'email' }))
app.get('/facebook/callback', passport.authenticate('facebook', {
successRedirect : '/',
failureRedirect : '/auth/facebook'
}))
使用上面的代码,我期望:
- 转到
/
- 被重定向到 facebook 进行登录
- 返回
/
- 已经
index.html
服务和加载 - 正确加载
script-a.js
和script-b.js
实际情况是:
我转到 /
,我被重定向到 /auth/facebook
,状态代码为 302
。
如果我删除:
app.use('/', ensureLoggedIn('/auth/facebook'), express.static(__dirname + '/public'))
改为手动声明每个路由处理程序,一切正常:
....
..
app.get('/', ensureLoggedIn('/auth/facebook'), (req,res) => {
res.sendFile(__dirname + '/public/index.html')
})
app.get('/script-a.js', ensureLoggedIn('/auth/facebook'), (req,res) => {
res.sendFile(__dirname + '/public/script-a.js')
})
app.get('/script-b.js', ensureLoggedIn('/auth/facebook'), (req,res) => {
res.sendFile(__dirname + '/public/scripts/script-b.js')
})
如果你的授权是这样实现的:
app.use('/public', ensureLoggedIn('/auth/facebook'));
然后,您可以 运行 在您的 express.static()
路线之前:
app.use(ensureLoggedIn('/auth/facebook'));
app.use(express.static(__dirname + '/public'));
或者,您将其专门合并到静态路由中:
app.use(ensureLoggedIn('/auth/facebook'), express.static(__dirname + '/public'));
When I also include the first 2 lines, not even the index.html gets served. I only get a failed facebook redirect registered on the network panel.
然后,您的身份验证中间件要么正确地拒绝对未经授权的客户端的访问,要么您的身份验证中间件无法正常工作。您的问题中没有任何内容表明可能是或可以让我们为您诊断。
But all other static files fail to be served.
为了帮助您解决这个问题,我们必须查看未正确提供的静态文件的具体信息(URL 在网页中,资源在您的文件系统中的位置, ETC...)。为了使静态文件正常工作,人们会犯 4-5 个常见错误。最常见的只是在网页中使用错误的 URL 静态资源,例如图像,CSS 文件,脚本文件等...
不幸的是,我找到的唯一解决方案是将我的 /public
文件夹变成平面结构并执行:
app.get('/', ensureLoggedIn('/auth/facebook'), (req,res) => {
res.sendFile(__dirname + '/public/index.html')
})
app.get('/:filename', ensureLoggedIn('/auth/facebook'), (req,res) => {
res.sendFile(__dirname + `/public/${req.params.filename}`)
})