node.js의 암호 및 암호 재설정 흐름을 잊어버렸습니다.
                                            
                                                
                                                
                                                
                                                
                                                
                                                 41118 단어  javascriptnodemongodb
                    
그럼 코딩을 시작해 볼까요?
데모 비디오
Project Github Link
앱 개요:
프로젝트 구조

다음 표는 내보낸 Rest API의 개요를 보여줍니다.
행동 양식
URL
행위
게시하다
/사용자
사용자 생성
게시하다
/비밀번호 초기화
비밀번호 재설정 링크 보내기
게시하다
/password-reset/:userId/:token
사용자 비밀번호 재설정
Node.js 앱 만들기
$ mkdir node-email-password-reset
$ cd node-email-password-reset
$ npm init --yes
$ npm install express mongoose dotenv nodemailer joi
Express : Express는 최소한의 유연한 Node.js 웹 애플리케이션 프레임워크입니다.
몽구스 : 몽구스는 MongoDB 및 Node.js용 객체 데이터 모델링(ODM) 라이브러리입니다.
Nodemailer : Nodemailer를 사용하면 이메일을 보낼 수 있습니다.
Joi : Joi는 자바스크립트 객체에 대한 객체 스키마 기술 언어이자 유효성 검사기입니다.
Dotenv : .env 파일에서 환경 변수를 로드합니다.
패키지.json
{
  "name": "node-email-password-reset",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "dotenv": "^9.0.2",
    "express": "^4.17.1",
    "joi": "^17.4.0",
    "mongoose": "^5.12.10",
    "nodemailer": "^6.6.0"
  }
}
익스프레스 웹 서버 설정
루트 폴더에서 index.js 파일을 생성해 보겠습니다.
require("dotenv").config();
const express = require("express");
const app = express();
app.use(express.json());
const port = process.env.PORT || 8080;
app.listen(port, () => console.log(`Listening on port ${port}...`));
환경 변수 구성
루트 폴더에서 .env 파일을 생성해 보겠습니다.
DB = // mongodb url
HOST = // email host
USER = // email id
PASS = // email password
SERVICE = // email service
BASE_URL = "http://localhost:8080/api"
MongoDB 데이터베이스 구성
루트 폴더에서 db.js 파일을 생성해 보겠습니다.
const mongoose = require("mongoose");
module.exports = connection = async () => {
    try {
        const connectionParams = {
            useNewUrlParser: true,
            useCreateIndex: true,
            useUnifiedTopology: true,
        };
        await mongoose.connect(process.env.DB, connectionParams);
        console.log("connected to database.");
    } catch (error) {
        console.log(error, "could not connect database.");
    }
};
index.js에서 db.js를 가져오고 호출합니다.
//....
const connection = require("./db");
const express = require("express");
const app = express();
connection();
app.use(express.json());
//....
모델 정의
루트 디렉토리에 models 폴더를 생성합니다.
모델/user.js는 다음과 같습니다.
const mongoose = require("mongoose");
const Schema = mongoose.Schema;
const Joi = require("joi");
const userSchema = new Schema({
    name: {
        type: String,
        required: true,
    },
    email: {
        type: String,
        required: true,
    },
    password: {
        type: String,
        required: true,
    },
});
const User = mongoose.model("user", userSchema);
const validate = (user) => {
    const schema = Joi.object({
        name: Joi.string().required(),
        email: Joi.string().email().required(),
        password: Joi.string().required(),
    });
    return schema.validate(user);
};
module.exports = { User, validate };
다음과 같은 models/token.js 파일:
const mongoose = require("mongoose");
const Schema = mongoose.Schema;
const tokenSchema = new Schema({
    userId: {
        type: Schema.Types.ObjectId,
        required: true,
        ref: "user",
    },
    token: {
        type: String,
        required: true,
    },
    createdAt: {
        type: Date,
        default: Date.now,
        expires: 3600,
    },
});
module.exports = mongoose.model("token", tokenSchema);
이메일 전송기 구성
루트 디렉터리에서 utils 폴더를 만듭니다.
utils/sendEmail.js 파일은 다음과 같습니다.
const nodemailer = require("nodemailer");
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.PASS,
            },
        });
        await transporter.sendMail({
            from: process.env.USER,
            to: email,
            subject: subject,
            text: text,
        });
        console.log("email sent sucessfully");
    } catch (error) {
        console.log(error, "email not sent");
    }
};
module.exports = sendEmail;
경로 정의
루트 디렉토리에서 경로 폴더를 작성하십시오.
route/users.js 파일은 다음과 같습니다.
const { User, validate } = require("../models/user");
const express = require("express");
const router = express.Router();
router.post("/", async (req, res) => {
    try {
        const { error } = validate(req.body);
        if (error) return res.status(400).send(error.details[0].message);
        const user = await new User(req.body).save();
        res.send(user);
    } catch (error) {
        res.send("An error occured");
        console.log(error);
    }
});
module.exports = router;
route/passwordReset.js 파일은 다음과 같습니다.
const { User } = require("../models/user");
const Token = require("../models/token");
const sendEmail = require("../utils/sendEmail");
const crypto = require("crypto");
const Joi = require("joi");
const express = require("express");
const router = express.Router();
router.post("/", async (req, res) => {
    try {
        const schema = Joi.object({ email: Joi.string().email().required() });
        const { error } = schema.validate(req.body);
        if (error) return res.status(400).send(error.details[0].message);
        const user = await User.findOne({ email: req.body.email });
        if (!user)
            return res.status(400).send("user with given email doesn't exist");
        let 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}/password-reset/${user._id}/${token.token}`;
        await sendEmail(user.email, "Password reset", link);
        res.send("password reset link sent to your email account");
    } catch (error) {
        res.send("An error occured");
        console.log(error);
    }
});
router.post("/:userId/:token", async (req, res) => {
    try {
        const schema = Joi.object({ password: Joi.string().required() });
        const { error } = schema.validate(req.body);
        if (error) return res.status(400).send(error.details[0].message);
        const user = await User.findById(req.params.userId);
        if (!user) return res.status(400).send("invalid link or expired");
        const token = await Token.findOne({
            userId: user._id,
            token: req.params.token,
        });
        if (!token) return res.status(400).send("Invalid link or expired");
        user.password = req.body.password;
        await user.save();
        await token.delete();
        res.send("password reset sucessfully.");
    } catch (error) {
        res.send("An error occured");
        console.log(error);
    }
});
module.exports = router;
프런트 엔드에서 이 경로를 사용하는 경우 passwordReset.js에 다른 경로가 필요할 수 있습니다. 링크가 유효한 경우에만 비밀번호 재설정 양식을 표시해야 합니다. 따라서 링크를 확인하고 암호 재설정 양식을 표시하는 GET 경로가 필요합니다.
index.js에서 경로 가져오기
//...
const passwordReset = require("./routes/passwordReset");
const users = require("./routes/users");
const connection = require("./db");
//.....
app.use(express.json());
app.use("/api/users", users);
app.use("/api/password-reset", passwordReset);
//....
그게 다야, 우편 배달부에서 API를 테스트해 보세요. 실수를 발견했거나 코드를 더 잘 만들면 댓글로 알려주세요. 더 나은 이해를 위해 Youtube 비디오를 시청하십시오. 매주 더 많은 지식 콘텐츠를 얻으려면 내 YouTube 채널을 구독하십시오.
아리가또 고자이마스.. 🙂
Reference
이 문제에 관하여(node.js의 암호 및 암호 재설정 흐름을 잊어버렸습니다.), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/cyberwolves/how-to-implement-password-reset-via-email-in-node-js-132m텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
                                
                                
                                
                                
                                
                                우수한 개발자 콘텐츠 발견에 전념
                                (Collection and Share based on the CC Protocol.)