注册过程中如何通过电子邮件验证用户

问题描述 投票:0回答:1

大家好,我正在尝试通过电子邮件实现用户验证。链接已发送到电子邮件,但单击链接时,这就是响应

找不到此本地主机页面 找不到该网址的网页:http://localhost:1001/activation/eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYW1lIjoiUEFVTCBPVU1BIE9DSE9MTEEiLCJlbWFpbCI6Im1hcmNvY2hvbGxhcGF1bDAxQGdtY WlsLmNvbSIsImF2YXRhciI6eyJ1cmwiOiJodHRwOi8vbG9jYWxob3N0OjEwMDAvdXBsb2Fkcy9mYXZpY29uLTE2OTQ5MDM4OTA0MTMtOTc2MDU1NDM1LnBuZyJ9LCJwYXNzd29yZCI6ImpoYmpqampq ampoYmoiLCJpYXQiOjE2OTQ5MDM4OTAsImV4cCI6MTY5NDkwNDE5MH0.UwrFTz4Yr-hGp7ddyIM-w85OI9BkVmT6eHQz5zzdAlk HTTP 错误 404

这是我的代码片段

用户控制器文件

const express = require(`express`);
const router = express.Router();
const User = require(`../models/user`);
const ErrorHandler = require(`../utils/ErrorHandler`);
const { upload } = require(`../multer`);
const fs = require(`fs`);
const uuid = require("uuid");
const jwt = require(`jsonwebtoken`);
const sendMail = require(`../utils/sendMail`);
const catchAsyncErrors = require("../middlewares/catchAsyncErrors");
const sendToken = require("../utils/jwtToken");

router.post("/create-user", upload.single("file"), async (req, res, next) => {
  const { name, email, password } = req.body;
  const userEmail = await User.findOne({ email });

  if (userEmail) {
    const filename = req.file.filename;
    const filepath = `uploads/${filename}`;

    fs.unlink(filepath, (err) => {
      if (err) {
        console.log(err);
        res.status(500).json({ message: `Error deleting file` });
      }
    });

    return next(new ErrorHandler(`User already exists`, 400));
  }

  const fileId = uuid.v4();
  const protocol = req.protocol;
  const host = req.get("host");
  const fileUrl = `${protocol}://${host}/uploads/${req.file.filename}`;

  const user = {
    name: name,
    email: email,
    avatar: fileUrl,
    password: password,
  };

  // Generate the activation token
  const activationToken = createActivationToken(user);

  // Construct the activation URL
  const activationUrl = `http://localhost:1001/activation/${activationToken}`;

  try {
    await sendMail({
      email: user.email,
      subject: "Activate Your Account",
      message: `Hello ${user.name}, please click on the link to activate your account: ${activationUrl}`,
    });
    res.status(201).json({
      success: true,
      message: `Please check your email: ${user.email} to activate your account`,
    });
  } catch (error) {
    return next(new ErrorHandler(error.message, 500));
  }
});



// Define a function to create an activation token
const createActivationToken = (user) => {
  return jwt.sign(user, process.env.ACTIVATION_SECRET, {
    expiresIn: "5m",
  });
};

router.post(
  "/activation",
  catchAsyncErrors(async (req, res, next) => {
    try {
      const { activation_token } = req.body;

      // Verify the activation token
      const newUser = jwt.verify(
        activation_token,
        process.env.ACTIVATION_SECRET
      );

      if (!newUser) {
        return next(new ErrorHandler("Invalid token", 400));
      }
      const { name, email, password, avatar } = newUser;

      let user = await User.findOne({ email });

      if (user) {
        return next(new ErrorHandler("User already exists", 400));
      }
      user = await User.create({
        name,
        email,
        avatar,
        password,
      });

      // Send the JWT token as a response
      sendToken(user, 201, res);
    } catch (error) {
      return next(new ErrorHandler(error.message, 500));
    }
  })
);

module.exports = router;

sendMail.js

const nodemailer = require(`nodemailer`);

const dotenv = require('dotenv');
dotenv.config({ path: '../config/.env' });

const sendMail = async (options) => {
  
  const transpoter = nodemailer.createTransport({
    host: process.env.SMTP_HOST ,
    port: process.env.SMTP_PORT ,
    secure: true,
    service: process.env.SMTP_SERVICE ,
    auth: {
      user: process.env.SMTP_MAIL ,
      pass: process.env.SMTP_PASSWORD ,
    },
  });

  const mailOptions = {
    from: process.env.SMTP_MAIL ,
    to: options.email,
    subject: options.subject,
    text: options.message,
  };

  await transpoter.sendMail(mailOptions);
};

module.exports = sendMail;

JwtToken.js

// create token and saving that in cookies
const sendToken = (user, statusCode, res) => {
  const token = user.getJwtToken();

  // Options for cookies
  const options = {
    expires: new Date(Date.now() + 90 * 24 * 60 * 60 * 1000),
    httpOnly: true,
  };

  res.status(statusCode).cookie(`token`, token, options).json({
    success: true,
    user,
    token,
  });
};

module.exports = sendToken; 

这是我的前端路线

<Route path='/activation/:activation_token' element={<ActivationPage />} />

激活页面.jsx

import  { useEffect, useState } from 'react'
import { useSearchParams } from 'react-router-dom'
import { BASE_URL } from '../config';
import axios from 'axios';

const ActivationPage = () => {
    const { activation_token } = useSearchParams();
    const [error, setError] = useState(false);

    useEffect(() => {
        if (activation_token) {
            const activationEmail = async () => {
                try {
                    const res = await axios.post(`${BASE_URL}/user/activation`, {
                        activation_token
                    });
                    console.log(res.data.message)
                } catch (error) {
                    console.log(error.response.data.message)
                    setError(true)
                }
            };
            activationEmail();
        }
    }, [activation_token])

    return (
        <div className='w-full h-screen flex justify-center items-center text-sm font-semibold'>
            {
                error ? (
                    <p>Your token is Expired!!</p>
                ) : (
                    <p>Your Account has been created successfully!!</p>
                )
            }
        </div>
    )
}

export default ActivationPage;

我期待看到一个带有“您的帐户已成功创建!”的页面

node.js reactjs express jwt nodemailer
1个回答
0
投票

由于您的 JWT 包含连字符或其他特殊字符,React Router 可能无法正确处理它。尝试用正则表达式包装 :activation_token 以接受所有字符。例如:

<Route path='/activation/:activation_token*' element={<ActivationPage />} />
© www.soinside.com 2019 - 2024. All rights reserved.