发送重置密码电子邮件的实现是否正确?



我已经阅读了这篇文章 https://ahrjarrett.com/posts/2019-02-08-resetting-user-passwords-with-node-and-jwt 了解如何在express中重置密码。

mailer.js

const nodemailer = require("nodemailer")
export const transporter = nodemailer.createTransport({
service: "gmail",
auth: {
user: process.env.EMAIL,
pass: process.env.PASSWORD
}
})
export const getPasswordResetURL = (user, token) => {
`http://localhost:3000/password/reset/${user._id}/${token}`
}
export const resetPasswordTemplate = (user, url) => {
const from = process.env.EMAIL
const to = user.email
const subject = "Password Reset"
const html = `
<p>Hey ${user.name || user.email},</p>
<p>We heard that you forgot your password. Sorry about that!</p>
<p>But don’t worry! You can use the following link to reset your password:</p>
<a href=${url}>${url}</a>
<p>If you don’t use this link within 1 hour, it will expire.</p>
`
}
return { from, to, subject, html }
emailController.js

const jwt = require("jsonwebtoken")
const bcrypt = require("bcrypt")
const User = require("../models/User")
import { transporter, getPasswordResetURL, resetPasswordTemplate } from "../utils/mailer"
export const usePasswordHashToMakeToken = ({
password: passwordHash,
_id: userId,
createdAt
}) => {
const secret = passwordHash + "-" + createdAt
const token = jwt.sign({ userId }, secret, {
expiresIn: 3600 // 1 hour
})
return token
}
export const sendPasswordResetEmail = async (req, res) => {
const { email } = req.params
let user
try {
user = await User.findOne({ email }).exec()
} catch (err) {
res.status(404).json("No user with that email")
}
const token = usePasswordHashToMakeToken(user)
const url = getPasswordResetURL(user, token)
const emailTemplate = resetPasswordTemplate(user, url)
const sendEmail = () => {
transporter.sendMail(emailTemplate, (err, info) => {
if (err) {
res.status(500).json("Error sending email")
}
console.log(`** Email sent **`, info.response)
})
}
sendEmail()
}
export const receiveNewPassword = (req, res) => {
const { userId, token } = req.params
const { password } = req.body
User.findOne({ _id: userId })
.then(user => {
const secret = user.password + "-" + user.createdAt
const payload = jwt.decode(token, secret)
if (payload.userId === user.id) {
bcrypt.genSalt(10, function(err, salt) {
if (err) return
bcrypt.hash(password, salt, function(err, hash) {
if (err) return
User.findOneAndUpdate({ _id: userId }, { password: hash })
.then(() => res.status(202).json("Password changed accepted"))
.catch(err => res.status(500).json(err))
})
})
}
})
.catch(() => {
res.status(404).json("Invalid user")
})
}
users.js
const express = require('express');
const router = express.Router();
const userController = require("../controllers/userController")
const emailController = require("../controllers/emailController")
router.post("/register", userController.registerUser)
router.post("/login", userController.loginUser)
router.get("/:userId", userController.getUser)
router.post("/user/:email", emailController.sendPasswordResetEmail)
router.post("/receive_new_password/:userId/:token", emailController.receiveNewPassword)

module.exports = router;

它给了我意外令牌 { 在此行中的

错误import { transporter, getPasswordResetURL, resetPasswordTemplate } from "../utils/mailer">

我可以将此导出常量转换为模块导出并通过以下方式要求上述内容吗:

const { transporter, getPasswordResetURL, resetPasswordTemplate } = require("../utils/mailer"(

正如您在问题中提到的,请替换所有导出常量并将其替换为

module.exports = {transporter, getPasswordResetURL, resetPasswordTemplate}

同时更换行

import { transporter, getPasswordResetURL, resetPasswordTemplate } from "../utils/mailer"

const { transporter, getPasswordResetURL, resetPasswordTemplate } = require("../utils/mailer")

作为导入,导出是 es6 语法和必需,module.exports 是 es5 语法。如果你想使用import,那么你需要配置Babel。

建议

最有可能的例子是他同时使用 es6 和 es5 语法(他一定配置了 babel(。但是就您而言,我认为您没有配置babel。所以我建议你要么配置 babel,要么将所有 es6 语法更改为 es5。在 es6 中,您可以使用 es5,但在 es5 中不能使用 es6

最新更新