【问题标题】:Express & Firebase - Failing to set header before redirectExpress & Firebase - 无法在重定向前设置标头
【发布时间】:2018-11-26 18:13:04
【问题描述】:

我正在尝试在服务器上进行 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");
});

/login POST 路由中,我按预期收到了idToken(并显示在日志中)。 但似乎响应无法保留/维护预先设置的标头属性Authentication: Bearer &lt;Firebase ID token&gt;

事实上,我在 Postman 中向 /dashboard 发送了一个 GET 请求,方法是获取日志打印的 idToken 并将其设置在请求的标头中,例如 Authorization: Bearer &lt;idToken&gt;,它运行良好。

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

【问题讨论】:

    标签: node.js firebase express firebase-authentication google-cloud-functions


    【解决方案1】:

    您必须在每个请求中发送授权标头。 HTTPS 函数是无状态的。他们不记得先前请求中的任何内容。因此,您不应依赖重定向行为来保留状态。相反,客户端需要弄清楚下一步要去哪里并自己发出下一个请求。

    【讨论】:

    • 您能详细说明一下吗?我没太明白。 express 不是要接收 idToken 并使用 admin SDK 进行验证吗?我该怎么办?
    • 我明白我必须从客户端发送 idToken (这将是从 AuthStateChanged 回调内部发出请求的最佳方式?),但我如何确保授权标头在每个请求中?
    • 在我的回答中,我说你不应该依赖重定向。找到另一种不使用重定向来完成工作的方法,因为它不允许您在重定向请求中指定标头。
    • 您有什么建议吗?
    猜你喜欢
    • 2015-11-21
    • 1970-01-01
    • 1970-01-01
    • 2019-04-29
    • 2021-01-03
    • 2012-07-13
    • 2019-12-29
    • 2018-05-05
    • 2017-08-11
    相关资源
    最近更新 更多