Node.js 特快专递及;Firebase-在重定向之前设置标头失败

Node.js 特快专递及;Firebase-在重定向之前设置标头失败,node.js,firebase,express,firebase-authentication,google-cloud-functions,Node.js,Firebase,Express,Firebase Authentication,Google Cloud Functions,我正在尝试使Firebase身份验证在服务器上工作 'use strict'; const functions = require('firebase-functions'); const admin = require('firebase-admin'); admin.initializeApp(); const express = require('express'); const bodyParser = require('body-parser'); const cookieParse

我正在尝试使Firebase身份验证在服务器上工作

'use strict';

const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp();
const express = require('express');
const bodyParser = require('body-parser');
const cookieParser = require('cookie-parser')();
const cors = require('cors')({origin: true});
//const expressSanitizer = require('express-sanitizer');
const app = express();

// Express middleware that validates Firebase ID Tokens passed in the Authorization HTTP header.
// The Firebase ID token needs to be passed as a Bearer token in the Authorization HTTP header like this:
// `Authorization: Bearer <Firebase ID Token>`.
// when decoded successfully, the ID Token content will be added as `req.user`.

const validateFirebaseIdToken = (req, res, next) => {
   console.log('Check if request is authorized with Firebase ID token');

   if ((!req.headers.authorization || !req.headers.authorization.startsWith('Bearer ')) &&
  !(req.cookies && req.cookies.__session)) {
       console.error('No Firebase ID token was passed as a Bearer token in the Authorization header.',
    'Make sure you authorize your request by providing the following HTTP header:',
    'Authorization: Bearer <Firebase ID Token>',
    'or by passing a "__session" cookie.');
    res.redirect("/login");
    return;
   }

   let idToken;
   if (req.headers.authorization && req.headers.authorization.startsWith('Bearer ')) {
   console.log('Found "Authorization" header');
     // Read the ID Token from the Authorization header.
     idToken = req.headers.authorization.split('Bearer ')[1];
   } else if(req.cookies) {
     console.log('Found "__session" cookie');
     // Read the ID Token from cookie.
     idToken = req.cookies.__session;
   } else {
     // No cookie
     res.redirect("/login");
     return;
   }

   admin.auth().verifyIdToken(idToken).then((decodedIdToken) => {
      console.log('ID Token correctly decoded', decodedIdToken);
      req.user = decodedIdToken;
      return next();
   }).catch((error) => {
      console.error('Error while verifying Firebase ID token:', error);
      res.redirect("/login");
   });
 };

app.use(bodyParser.urlencoded({ extended: true }));
app.use(express.static("/public"));
app.use(cors);
app.use(cookieParser);
//app.use(expressSanitizer());
//app.use(validateFirebaseIdToken);=
app.set("view engine", "ejs");

// This HTTPS endpoint can only be accessed by your Firebase Users.
// Requests need to be authorized by providing an `Authorization` HTTP header
// with value `Bearer <Firebase ID Token>`.
exports.app = functions.https.onRequest(app);



app.post("/login", (request, response) => {

   var idToken = request.body.token;

   console.log("REQUEST BODY = " + idToken);

   response.header("Authorization" , "Bearer " + idToken);

   return response.redirect("dashboard");
});

app.get("/dashboard", validateFirebaseIdToken, (request, response) => {
   response.redirect("/dashboard/new");
});
“严格使用”;
const functions=require('firebase-functions');
const admin=require('firebase-admin');
admin.initializeApp();
const express=require('express');
const bodyParser=require('body-parser');
const cookieParser=require('cookie-parser')();
const cors=require('cors')({origin:true});
//const expressSanitizer=require('express-sanitizer');
常量app=express();
//验证在授权HTTP头中传递的Firebase ID令牌的Express中间件。
//Firebase ID令牌需要作为承载令牌在授权HTTP头中传递,如下所示:
//“授权:持票人”。
//解码成功后,ID令牌内容将添加为“req.user”。
const validateFireBaisedToken=(请求、恢复、下一步)=>{
log('检查请求是否使用Firebase ID令牌授权');
if((!req.headers.authorization | |!req.headers.authorization.startsWith('Bearer'))&&
!(请求cookies和请求cookies.\uuu会话)){
console.error('授权标头中没有作为承载令牌传递Firebase ID令牌。',
'请确保通过提供以下HTTP标头来授权您的请求:',
“授权:持票人”,
'或通过传递一个“uu会话”cookie.”);
res.redirect(“/login”);
返回;
}
让idToken;
if(req.headers.authorization&&req.headers.authorization.startsWith('Bearer')){
log('Found“Authorization”header');
//从授权标头读取ID令牌。
idToken=req.headers.authorization.split('Bearer')[1];
}else if(请求cookies){
log('Found“\uuuu session”cookie');
//从cookie中读取ID令牌。
idToken=请求cookies.\uuuu会话;
}否则{
//没有饼干
res.redirect(“/login”);
返回;
}
admin.auth().verifyIdToken(idToken)。然后((decodedIdToken)=>{
log('ID令牌正确解码',decodedIdToken);
req.user=decodedIdToken;
返回next();
}).catch((错误)=>{
console.error('验证Firebase ID令牌时出错:',错误);
res.redirect(“/login”);
});
};
use(bodyParser.urlencoded({extended:true}));
应用程序使用(快速静态(“/public”);
应用程序使用(cors);
应用程序使用(cookieParser);
//app.use(expressSanitizer());
//应用程序使用(ValidateFireBaisedToken)=
应用程序集(“查看引擎”、“ejs”);
//此HTTPS端点只能由Firebase用户访问。
//请求需要通过提供“Authorization”HTTP头进行授权
//值为'Bearer`。
exports.app=functions.https.onRequest(app);
app.post(“/login)”,(请求、响应)=>{
var idToken=request.body.token;
console.log(“请求主体=“+idToken”);
响应头(“授权”、“承载人”+idToken);
返回响应。重定向(“仪表板”);
});
app.get(“/dashboard”,validateFileBasedToken,(请求,响应)=>{
响应。重定向(“/dashboard/new”);
});
/login
POST路径中,我收到了预期的
idToken
(并显示在日志中)但是,响应似乎无法保留/维护预先设置的头属性
Authentication:Bearer

事实上,我在Postman中向
/dashboard
发送了一个GET请求,方法是获取日志打印的idToken,并将其设置在请求的头中,如
Authorization:Bearer
,它工作得非常好


重定向实际上是新的HTTPS请求,因此不会保留响应中设置的头。在这种情况下我该怎么办?

您必须在每个请求中发送授权标头。HTTPS函数是无状态的。他们不记得以前的要求。所以,您不应该依赖重定向行为来保留状态。相反,客户需要确定下一步要去哪里,并自己提出下一个请求。

您能详细说明一下吗?我不太明白。express不打算接收idToken并使用AdminSDK进行验证吗?我应该怎么做?我知道我必须从客户端发送idToken(这是从
AuthStateChanged
回调内部执行请求的最佳方式),但我如何确保每个请求中都有授权标头?在我的回答中,我说不应该依赖重定向。找到另一种不用重定向就能完成工作的方法,因为它不会让你在重定向请求中指定头。你有什么建议吗?