Firebase Functions HTTPS 403 禁止使用



我用Node和Express构建了一个Firebase HTTP Event函数。该函数正在工作,但是当我在客户端调用该函数时,我得到403 Forbidden.我第一次调用该函数时,我被要求使用 Google 帐户登录。我使用与Firebase相同的帐户登录,但是当我调用该函数时,我得到了:

403 错误的屏幕截图

我查看了Google云平台上的使用角色,调用该函数的权限设置为allUsers。我在Firebase CLI中退出并重新登录。

以下是函数文件夹中的index.js

const functions = require('firebase-functions');
const express = require('express');
const app = express();
const bodyParser = require('body-parser');
const port = process.env.port || 5600
const nodemailer = require('nodemailer');
app.use(express.static('Public'));
app.use(bodyParser.urlencoded({ extended: true }));
const urlencodedParser = bodyParser.urlencoded({extended: true});
app.post("/api/user", urlencodedParser, (req, res) => {
res.sendFile('../Public/bedankt.html', {root: __dirname})
const persGegevens = req.body
const string = JSON.stringify(persGegevens, (key, value) => {
if (typeof value === "string"){
return value.toUpperCase();
} else {
return value
}
}, 1);
var transporter = nodemailer.createTransport({
service: 'gmail',
auth: {
user: 'gietvloermakers@gmail.com',
pass: 'Gietvloermakers2020!'
}
});
var mailOptions = {
from: 'gietvloermakers@gmail.com',
to: 'gvbeusekom84@hotmail.com',
subject: 'Nieuwe bestelling op Gietvloermakers',
html: string
};
transporter.sendMail(mailOptions, function(error, info){
if (error) {
console.log(error);
} else {
console.log('Email sent: ' + info.response);
}
});
});
exports.app1 = functions.https.onRequest(app);
app.listen(port);
console.log(port);

这是 html:

<form id="controlleer-form" action="/api/user" method="post" enctype="application/x-www-form-urlencoded">
<div class="controleer-div">
<h2>Uw bestelling</h2>
<p>Aantal m2</p>
<input class="controle-input" type="text" name="aantalM2" id="aantalM2" readonly>
<p>Kleur</p>
<input class="controle-input" type="text" name="kleur" id="kleur" readonly>
<p>Assistentie</p>
<input class="controle-input" type="text" name="assistentie" id="assistentie" readonly>
<p>Gereedschappen</p>
<input class="controle-input" type="text" name="gereedschappen" id="gereedschappen" readonly>
<p>Totale prijs</p>
<input  class="controle-input" type="text" name="totale-prijs" id="totale-prijs" readonly>
<a href="bestellen.html"><p id="andere-kleur">Bestelling aanpassen</p></a>
</div>
<div class="controleer-div">
<h2>Uw gegevens</h2>
<p>Voornaam</p>
<input type="text" name="voornaam" placeholder="Voornaam">
<p>Achternaam</p>
<input type="text" name="Achternaam" placeholder="Achternaam">
<p>Straatnaam en huisnummer</p>
<input type="text" name="Achternaam" placeholder="Straatnaam en huisnummer">
<p>Postcode</p>
<input type="text" name="Achternaam" placeholder="Postcode">
<p>Telefoonnummer</p>
<input type="tel" name="telefoonnummer" placeholder="Telefoonnummer">
<p>Emailadres</p>
<input type="email" name="email" placeholder="Emailadres"><br>
<input id="verzenden" type="submit"> 
</div>
</form>

这是firebase.json:

{
"hosting": {
"public": "Public",
"ignore": [
"firebase.json",
"**/.*",
"**/node_modules/**"
],
"rewrites": [{
"source": "**",
"function": "app1"
}]
}
}

我试过了,但我用尽了到目前为止在网上找到的所有可能的解决方案。

我最近遇到了这个问题。事实证明,截至 2020 年 1 月 15 日,默认情况下,新功能需要身份验证。

有关详细信息,请参阅此处的文档。

解决方案是在 Google 云控制台的"云功能"页面中手动将Cloud Functions Invoker权限添加到allUsers用户。

如果您收到如下所示的 403 禁止错误

错误:禁止 您的客户端无权获取 URL 来自此服务器的/api/test。

请按照以下步骤向所有用户授予访问权限。基本上,这是为了允许未经身份验证的客户端访问您的 api 终端节点。

  • 转到 https://console.cloud.google.com/functions/list
  • 选择要授予公共访问权限
  • 的功能
  • 点击权限
  • 点击添加成员
  • 键入所有用户
  • 选择角色云函数 ->云函数调用程序

就是这样,现在测试您的 api。

这与对您的云函数 http 请求和云函数事件的权限访问有关,您需要编辑您的云函数 IAM 权限。

https://cloud.google.com/functions/docs/securing/managing-access-iam#allowing_unauthenticated_function_invocation

遇到同样的问题(被要求使用我的Google帐户登录,然后被拒绝访问(。事实证明,函数目前在默认区域之外不起作用。就我而言,我必须在这里进行更改:

exports.app = functions
.region('europe-west6') // does not work, delete this line
.https.onRequest(app);

代码将快速应用程序导出为云函数app1在以下行:

exports.app1 = functions.https.onRequest(app);

在屏幕截图中,您尝试访问不存在的app云函数,而是导致403 Forbidden响应。

这意味着从客户端调用的正确 URL 是

http://us-central1-gietvloermakers.cloudfunctions.net/app1/api/user
^^^^

(或者您可以将导出的名称更改为app(

仔细查看源代码后,还应删除以下行。如果你想测试你的代码,你会改用firebase serve

const port = process.env.port || 5600
/* ... */
app.listen(port);

在以下行中,您还将注入正文解析器两次。

app.use(bodyParser.urlencoded({ extended: true })); // use this
const urlencodedParser = bodyParser.urlencoded({extended: true}); // or this, not both
app.post("/api/user", urlencodedParser, ...

在代码中,您还具有:

app.post("/api/user", urlencodedParser, (req, res) => {
res.sendFile('../Public/bedankt.html', {root: __dirname})
/* do some other stuff */
})

这对于云函数无效,因为一旦云函数处理程序(您的代码(调用end()redirect()send(),云函数就可以随时终止,这意味着您的电子邮件可能永远不会被发送。要解决此问题,您需要最后发送文件。

app.post("/api/user", urlencodedParser, (req, res) => {
/* do some other stuff */
res.sendFile('../Public/bedankt.html', {root: __dirname})
});

我最后的观察是,错误可能是由服务器上不存在的文件夹Public引起的。根据sendFile调用,您期望文件夹"Public"可用于已部署的函数,但由于它不在functions文件夹中,因此不会与您的代码一起部署。

res.sendFile('../Public/bedankt.html', {root: __dirname})

由于此文件也可以在your-domain.com/bedankt.html访问,我们将重定向到它。如果要改为发送此文件的 HTML 内容,请将其移动到已部署的函数目录中。

res.redirect('/bedankt.html')

由于您似乎在尝试在 Firebase 主机背后使用快捷功能,因此我们可以将您的index.js文件修剪为以下内容:

const functions = require('firebase-functions');
const express = require('express');
const bodyParser = require('body-parser');
const nodemailer = require('nodemailer');
const apiApp = express();
apiApp.use(bodyParser.urlencoded({ extended: true }));
apiApp.post("/api/user", (req, res) => {
const persGegevens = req.body
const string = JSON.stringify(persGegevens, (key, value) => {
if (typeof value === "string"){
return value.toUpperCase();
} else {
return value
}
}, 1);
var transporter = nodemailer.createTransport({
service: 'gmail',
auth: {
user: 'gietvloermakers@gmail.com',
pass: 'Gietvloermakers2020!'
}
});
var mailOptions = {
from: 'gietvloermakers@gmail.com',
to: 'gvbeusekom84@hotmail.com',
subject: 'Nieuwe bestelling op Gietvloermakers',
html: string
};
transporter.sendMail(mailOptions, function(error, info){
if (error) {
console.log(error);
res.redirect('/bedankt.html?success=0');
} else {
console.log('Email sent: ' + info.response);
res.redirect('/bedankt.html?success=1');
}
});  
});
// note rename to api
exports.api = functions.https.onRequest(apiApp);

这需要将firebase.json文件更新为:

{
"hosting": {
"public": "Public",
"ignore": [
"firebase.json",
"**/.*",
"**/node_modules/**"
],
"rewrites": [{
"source": "/api/**",
"function": "api"
}]
}
}

此配置将首先尝试在Public目录中查找匹配的文件。如果找不到匹配项,它将检查请求的路径是否以/api开头,如果是,则启动您的云函数。如果仍然找不到匹配项,它将显示您的 404 页面(如果不存在,则显示内置页面(。

对我来说的解决方案:

  1. 删除 https://console.cloud.google.com/artifacts/browse/{项目名称} 中的gcf-artifacts

  2. 删除 https://console.firebase.google.com/u/0/project/{项目名称}/函数中的函数

  3. 部署 Firebase 函数

相关内容

  • 没有找到相关文章

最新更新