MERN 应用程序(nodemailer)中的内容安全策略错误

Content Security Policy Error in MERN App (nodemailer)

我正在开发 MERN App,一个 Blogify。我创建了一个注册并登录。现在我使用 nodemailer 创建了“忘记密码”操作。

我在开发环境和生产环境都能成功发送邮件。我在开发环境点击邮件收到的link,运行成功,但是在生产环境点击,出现如下错误

接收邮件示例:(..link/forgot-password/:userId/:token)

请按照link重置密码->https://codermocha.herokuapp.com/forgot-password/6196521181b12d4804d639b5/69849684469c15339328e0744fc6de0a6db993ce83b88838720e927c1ca5a7bf

Error page after clicking

错误消息:拒绝应用内联样式,因为它违反了以下内容安全策略指令:“style-src https://gc.kis.v2.scr.kaspersky-labs.com wss://gc.kis.v2.scr.kaspersky-labs.com”。启用内联执行需要 'unsafe-inline' 关键字、散列 ('sha256-JUCCMgPUsmi3ZsiQj4jAd7Uy7nrvEJzzDwDynfMpvuM=') 或随机数 ('nonce-...')。

密码控制器

export const passwordResetRequest = expressAsyncHandler(async (req, res) => {
  const email = req.body.email;
  if (!email)
    return res.status(400).json({ message: "Please enter an email!" });

  const user = await User.findOne(req.body);
  if (!user) return res.status(400).json({ message: "User does not exist!" });

  const token = await Token.findOne({ userId: user._id });
  if (!token) {
    token = await new Token({
      userId: user._id,
      token: crypto.randomBytes(32).toString("hex"),
    }).save();
  }

  const link = `${process.env.BASE_URL}${user._id}/${token.token}`;
  await sendEmail(user.email, "Password Reset", link);

  res
    .status(200)
    .json({ message: "Password reset link sent to your email account" });
});

export const passwordReset = expressAsyncHandler(async (req, res) => {
  console.log(req.body);
  const { newPassword, confirmPassword } = req.body;
  const { userId, token } = req.params;
  if (!newPassword || !confirmPassword)
    return res.status(400).json({ message: "Please check your fileds!" });

  const user = await User.findById({ _id: userId });
  if (!user)
    return res.status(404).json({ message: "Invalid link or expired" });

  const tokenDb = await Token.findOne({ userId: user._id, token });
  if (!tokenDb)
    return res.status(404).json({ message: "Invalid link or expired" });

  user.password = newPassword;
  await user.save();
  await tokenDb.delete();

  res.status(200).json({ message: "Password reset is successfull." });
});

发送邮件助手功能

const sendEmail = async (email, subject, text) => {
  try {
    const transporter = nodemailer.createTransport({
      host: process.env.HOST,
      service: process.env.SERVICE,
      port: 587,
      secure: true,
      auth: {
        user: process.env.USER,
        pass: process.env.PASSWORD,
      },
    });

    await transporter.sendMail({
      from: process.env.USER,
      to: email,
      subject,
      text: `Please follow the link to reset your password -> ${text}`,
    });

    console.log("Email başarıyla gönderildi");
  } catch (err) {
    console.log(err);
  }
};

您收到的错误表明您应用到显示页面的样式不是来自经过验证的来源。只有来源为(即来自)https://gc.kis.v2.scr.kaspersky-labs.com or wss://gc.kis.v2.scr.kaspersky-labs.com will be allowed to be used. (Reference - https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/style-src#examples)

的样式

请检查您的回复 header 中的 Content-Security-Policy 是否可以修改。您还可以将错误中给出的 SHA 添加到您的 CSP header 类似这样的东西 -

style-src :  'https://gc.kis.v2.scr.kaspersky-labs.com' 'wss://gc.kis.v2.scr.kaspersky-labs.com' 'sha256-JUCCMgPUsmi3ZsiQj4jAd7Uy7nrvEJzzDwDynfMpvuM'

我以不同的方式找到了解决方案。

应用程序中的文件夹结构是嵌套的。我 运行 使用 Concurrently 包将前端和后端一起使用。更改文件夹结构后,我的问题就解决了。

我把前端和后端放在了不同的文件夹里,分别部署了。

**Before**
-config
-models
-controllers
-routers
-front-end
 ..react folders and files
-index.js

**After**
-back-end
 ..node.js folders and files
-front-end
 ..react folders and files