你的两个选项都可以工作。
-
使用带有云功能的其余 api,您可以集成 Google Captcha。
-
直接使用数据库,您可以编写数据库规则,每个人都只能添加一个新联系人,而不能读取或编辑它。这仍然不太安全,因为有人可能会填满您的数据库。但是如果有一个非常好的字段验证和重复限制,这将是一个“较小”的问题。
以下是我们在网站上的做法:
处理captcha和联系POST的云函数:
const functions = require("firebase-functions");
const admin = require("firebase-admin");
admin.initializeApp();
const rp = require("request-promise");
const nodemailer = require("nodemailer");
const gmailEmail = encodeURIComponent(functions.config().gmail.email);
const gmailPassword = encodeURIComponent(functions.config().gmail.password);
const mailTransport = nodemailer.createTransport(
`smtps://${gmailEmail}:${gmailPassword}@smtp.gmail.com`
);
exports.checkRecaptcha = functions
.region("europe-west1")
.https.onRequest((req, res) => {
const response = req.query.response;
console.log("recaptcha response", response);
rp({
uri: "https://recaptcha.google.com/recaptcha/api/siteverify",
method: "POST",
formData: {
secret: "TOP_SECRET",
response: response,
},
json: true,
})
.then((result) => {
console.log("recaptcha result", result);
if (result.success) {
res.send("You're good to go, human.");
} else {
res.send("Recaptcha verification failed. Are you a robot?");
}
})
.catch((reason) => {
console.log("Recaptcha request failure", reason);
res.send("Recaptcha request failed.");
});
});
exports.triggerEmail = functions
.region("europe-west1")
.https.onRequest((req, res) => {
if (req.method !== "POST") {
res.status(400).send("Please send a POST request");
return;
}
const values = JSON.parse(req.body);
const email = "email@company.com";
const bcc = "email@company.com";
const mailOptions = {
subject: "Kontakt von Website",
text: `Datum: ${values.dateTime}\n
Name: ${`${values.gender} ${values.firstname} ${values.lastname}`}
Firmenname: ${values.company ? values.company : ""}
Strasse: ${values.street ? values.street : ""}
Ort: ${values.place ? values.place : ""}
Land: ${values.country ? values.country : ""}
PLZ: ${values.zip ? values.zip : ""}
E-Mail: ${values.email ? values.email : ""}\n\n
${values.text ? values.text : ""}`,
to: email,
bcc: bcc,
};
console.log(req.headers.origin);
if (
req.headers.origin == "https://www.your_company.com" ||
req.headers.origin == "http://localhost:3000"
) {
res.setHeader("Access-Control-Allow-Origin", req.headers.origin);
}
return mailTransport.sendMail(mailOptions).then(() => {
res.status(200).send("OK");
});
});
我们这边的验证码使用反应:
<ReCAPTCHA
ref='recaptcha'
sitekey='SECRET_KEY'
onChange={response => this.setState({ response: response })}
/>
还有联系人POST拨打:
fetch('https://URL_TO_YOUR_FUNCTION_THAT_SENDS_THE_EMAIL', {
method: 'POST',
body: JSON.stringify({
dateTime: new Date().toString(),
gender: this.state.gender,
firstname: this.state.firstname,
lastname: this.state.lastname,
company: this.state.company,
street: this.state.street,
place: this.state.place,
country: this.state.country,
zip: this.state.zip,
email: this.state.email,
text: this.state.text,
isLogistik: isLogistik
})
})
确保您的验证码设置已设置为我们的第二个云功能进行验证。