我正在尝试在客户端使用Firebase和NodeJS与ejs模板构建Web应用程序。我想确保用户通过中间件访问特定路由之前已通过身份验证。在此中间件中,我将验证通过客户端发送的ID令牌,如果它们经过验证,则将呈现页面。但是当令牌通过验证后,该应用不会显示新页面,即“ user-profile.ejs”。
<button onclick="sendRequest('/profile')">Profile</button>
//The client function which sends ID token
function sendRequest(url){
if(firebase.auth().currentUser){
firebase.auth().currentUser.getIdToken(true)
.then(idToken => {
client({
method: 'get',
url: url,
headers: {
'authtoken': idToken
}
})
.then(res => {
console.log("Auth token sent.")
})
.catch(err => {
console.log(err)
})
})
.catch(err => {
console.log(err)
})
}else{
client({
method: 'get',
url: url,
}).then(res => {
console.log("Request sent without header.")
})
.catch(err => {
console.log(err)
})
}
}
//The NodeJS server which contains the routes and checkAuth middleware
function checkAuth(req,res,next){
if(req.headers.authtoken){
console.log('Auth token with headers received. User has logged in.')
admin.auth().verifyIdToken(req.headers.authtoken)
.then(verifiedUser => {
console.log('Auth token verified')
return next()
})
.catch(err => {
console.log(err)
res.redirect('back')
})
}else{
console.log('Without header received.')
res.redirect('back')
}
}
app.get('/',(req,res)=>{
res.render('home')
})
app.get('/profile',checkAuth,(req,res)=>{
console.log("Reached user profile")
res.send("user-profile")
})
[请记住,当您重定向时,客户端会获得重定向的URL并发出全新的http请求。这将在您的服务器上启动一个全新的请求周期,该周期将再次遍历与该新URL匹配的所有中间件。
自动客户端重定向不包括原始响应中的自定义标头。如果那是您所期望的,那将行不通。如果您要通过Ajax调用手动进行重定向,则可以从重定向响应标头中手动获取令牌,然后将其手动添加到新的Ajax调用中并重定向到该位置。
[如果您期望浏览器或某些自动重定向来处理重定向,则他们不会从标头中获取令牌。因此,您的服务器将不得不将响应发送到原始URL而无需重定向,或者您必须将令牌放入可以承受重定向的内容中,例如重定向中的查询参数(通常是凭证的好主意),或者在cookie或与cookie绑定的服务器端会话对象中。