노드 가입을 이중 선택하십시오.js: 확인 이메일 보내기

35118 단어 nodetutorialjavascript
최초 발표 webdeasy.de!

The double opt-in procedure has established itself as the standard for all types of registrations on the Internet in recent years. I will show you here what exactly is behind it and how you can integrate Double Opt-In into your Node.js application.


이중 선택 가입 프로그램에서는 양식(예를 들어 사이트)에 등록하는 것 외에 전자 우편으로 활성화 링크를 보내고, 확인한 후에야 등록 과정이 완료되거나 등록이 검증될 수 있다.
대표적인 응용 분야는 다음과 같습니다.

  • Newsletter 구독 및 구독 취소,
  • 복권 등록 또는
  • 로그인 시스템
  • 이 강좌에서 우리는 노드의 기존 RestAPI에 이중 선택 가입 과정을 구축할 것이다.js 로그인 시스템.다른 강좌에서 Node를 사용하여 RestAPI를 만드는 방법을 보여 주었습니다.js는 Vue.js과 같은 우리의 전단에 연결합니다.

    튜토리얼 노드.js 로그인 시스템


    만약 완전한 시스템이 있고 이중 선택 가입 과정을 확장하고 싶다면, 계속 읽을 수 있습니다.그렇지 않으면, 링크된 강좌를 먼저 보십시오.
    아직 Node에 익숙하지 않으시면js, 먼저 basics of Node.js을 보십시오.

    카탈로그

  • 1. Advantages of Double Opt-In
  • 2. Install dependencies
  • 3. Adjust MySQL database structure
  • 4. Adjust Registration (/sign-up) and Login (/login) routes
  • 5. Validate e-mail address
  • 6. Check account activation at login
  • 7. Create verification route (/verify)
  • 8. Send confirmation mail
  • 9. Test Double Opt-In
  • 1. Double Opt-In의 장점

    Besides the normal Single Opt-In procedure, where you simply sign up for something – without further confirmation – there is also the better Double Opt-In procedure. The following diagram should explain the difference in the registration process:


    이중 선택 가입은 많은 장점이 있는데, 지금은 이미 모든 웹 응용 프로그램, 응용 프로그램 등의 이미 정해진 표준이 되었다.
    가장 중요한 사실은 모든 확인된 등록이 진실이라는 것이다.이것은 로봇이 표에 등록할 수 있지만 계정은 영원히 검증되지 않을 것이다. 왜냐하면 로봇은 전자 우편의 검증 링크를 확인할 수 없기 때문이다.
    또한 데이터 보호의 측면에서 볼 때 이것은 사용자가 명확하게 등록에 동의하기 때문에 유리할 수 있다.특히 유럽연합 국가에서는 어떤 경우 DSGVO가 이렇게 요구할 수도 있다.

    But attention: I cannot give a professional opinion on legal issues!


    이제 확인 이메일(NodeEmailer의 도움말)을 직접 보내고 링크를 활성화해서 즐겁게 놀기 시작합니다!🙂

    2. 설치 종속성

    So the first step is to install the required packages:


    다음 명령을 사용하여 패키지를 설치할 수 있습니다.
    npm install nodemailer email-validator
    

    3. MySQL 데이터베이스 구조 조정

    We now extend our existing users table by three more columns:


    전체 MySQL은 다음과 같습니다.

    Here again the hint: This tutorial is based on another tutorial from me: Node.js Login System with Express, JWT and MySQL (RestAPI)


    4. 등록(/등록) 및 로그인(/로그인) 노선 조정

    To fill in the new columns, we adjust our existing registration route (/sign-up) and login route (/route) a bit.

    To do this, we change the following lines: 11, 21-31, 40-44.

    Unfortunately I can't give line numbers or highlighted lines here. 😔 For a clearer representation look at the post on my blog webdeasy.de.


    새 값(이메일 주소, 토큰, 계정 상태)을 데이터베이스에 입력할 수 있도록 SQL 조회가 변경되었습니다.영패로서 우리는 uid 패키지의 유일한 ID와 사용자 ID를 사용합니다.
    40줄에서 우리는 sendOptInMail()에서 함수 mailer을 호출했다.우리는 8단계의 기능을 실현했다.
    // routes/router.js
    router.post("/sign-up", userMiddleware.validateRegister, (req, res, next) => {
      db.query(
        `SELECT * FROM users WHERE LOWER(username) = LOWER(${db.escape(
          req.body.username
        )}) OR LOWER(email) = LOWER(${db.escape(req.body.email)});`,
        (err, result) => {
          if (result.length) {
            return res.status(409).send({
              msg: "This username or email is already in use!",
            });
          } else {
            // username is available
            bcrypt.hash(req.body.password, 10, (err, hash) => {
              if (err) {
                return res.status(500).send({
                  msg: err,
                });
              } else {
                let email = req.body.email;
                let userID = uuid.v4();
                let token = uuid.v4();
                // has hashed pw => add to database
                db.query(
                  `INSERT INTO users (id, username, email, password, registered, active, token) VALUES ('${userID}', ${db.escape(
                    req.body.username
                  )}, '${email}', ${db.escape(
                    hash
                  )}, now(), 0, '${token}')`,
                  async (err, result) => {
                    if (err) {
                      throw err;
                      return res.status(400).send({
                        msg: err,
                      });
                    }
                    await mailer.sendOptInMail(
                      email,
                      userID,
                      token
                    );
                    return res.status(201).send({
                      msg: "Registered!",
                    });
                  }
                );
              }
            });
          }
        }
      );
    });
    
    sendOptInMail()으로 전화하려면 mailer을 포함해야 합니다.이를 위해 간단하게 파일을 만들 수 있습니다. 내용이 바로 나타납니다.
    // routes/router.js
    [...]
    const mailer = require("../lib/mailer.js");
    [...]
    

    5. 이메일 주소 확인

    To verify the entered e-mail address, we extend our middleware in users.js with the lines 11-16.

    There it is checked whether a value named email was passed in the body of our request and whether it is a valid email address. If not, an error message is returned. Otherwise the route will be executed with next() at the end.

    To validate the email we use the email-validator가방.당신도 자신의 정규 표현식을 사용하여 이 점을 실현할 수 있지만, 간단하게 말하자면, 우리는 이곳에서 외부 모듈을 사용했다.
    // middleware/users.js
    validateRegister: (req, res, next) => {
        // username min length 3
        if (!req.body.username || req.body.username.length < 3) {
          return res.status(400).send({
            msg: "Please enter a username with min. 3 chars",
          });
        }
        // valide email
        if (!req.body.email || !validator.validate(req.body.email)) {
          return res.status(400).send({
            msg: "Please enter a valid email address",
          });
        }
        // password min 6 chars
        if (!req.body.password || req.body.password.length < 6) {
          return res.status(400).send({
            msg: "Please enter a password with min. 6 chars",
          });
        }
        // password (repeat) does not match
        if (
          !req.body.password_repeat ||
          req.body.password != req.body.password_repeat
        ) {
          return res.status(400).send({
            msg: "Both passwords must match",
          });
        }
        next();
      },
    

    6. 로그인 시 계정 활성화 확인

    In the /login route you can add this query, so that you can’t login if the account hasn’t been confirmed yet. In my case the query is after checking if a corresponding database entry exists. From line 20 of the /login route, if you want to orientate yourself at my other tutorial.

    // routes/router.js
    [...]
    if (!result[0]["active"]) {
      return res.status(401).send({
        msg: "Your account is not activated!",
      });
    }
    [...]
    

    If you have already extended the system with your own function, you should add this query in other relevant places, e.g. in a forget-password function.

    7. 검증 경로 만들기(/검증)

    With the verification route we can activate a registered account. We will send the link in the last step by mail. The link consists of the user ID and the unique token.

    To do this, we create a new route that reads the user from the database using the user ID. First we check if the entry exists at all and return an error message if necessary.

    From line 25 we check if the account is already activated and from line 32 we check the token.

    If all checks are correct, we set the user account active (from line 39) and return a success message with status code 200.

    // routes/router.js
    router.get("/verify/:userID/:token", (req, res, next) => {
      let userID = req.params.userID;
      let token = req.params.token;
      db.query(
        `SELECT * FROM users WHERE id = ${db.escape(userID)}`,
        (err, result) => {
          // user does not exists
          if (err) {
            throw err;
            return res.status(400).send({
              msg: err,
            });
          }
          // no result from database
          if (!result.length) {
            return res.status(409).send({
              msg: "The requested parameters are incorrect!",
            });
          }
          // already activated
          if (result[0]["active"]) {
            return res.status(409).send({
              msg: "Account is already activated!",
            });
          }
          // wrong activation token
          if (result[0]["token"] !== token) {
            return res.status(401).send({
              msg: "The requested parameters are incorrect!",
            });
          }
          // set account active
          db.query(
            `UPDATE users SET active = 1 WHERE id = '${userID}'`,
            (err, result) => {
              if (err) {
                throw err;
                return res.status(400).send({
                  msg: err,
                });
              }
              return res.status(200).send({
                msg: "Account activated",
              });
            }
          );
        }
      );
    });
    

    8. 확인 메일 보내기

    The confirmation mail contains a verification link, when called the account should be confirmed, i.e. activated. We assemble the link ourselves and send it with the nodemailer가방.
    이를 위해, 우리는 메일 프로그램을 만들 수 있다.js, NodeEmailer 포함
    이제 NodeEmailer를 설정하여 메일 서버를 통해 메일을 보냅니다.이것은 5행에서 16행까지의 createTransport() 함수를 통해 이루어진 것이다.
    메일 서버의 접근 데이터를 노드의 환경 변수로 표시해야 합니다.js(process.env.*). 따라서 원본 코드에 직접적인 민감한 데이터가 없기 때문에 서로 다른 개발과 생산 단계에서 데이터를 쉽게 조정할 수 있습니다.
    // lib/mailer.js
    const nodemailer = require("nodemailer");
    let transporter = nodemailer.createTransport({
      host: process.env.MAIL_HOST,
      port: 465,
      secure: true,
      auth: {
        user: process.env.MAIL_USER,
        pass: process.env.MAIL_PASSWORD,
      },
      tls: {
        rejectUnauthorized: false,
      },
    });
    
    이제 비동기 함수 sendOptInMail()을 만듭니다.사용자 ID와 영패에 따라 활성화 링크를 구축합니다./verify 루트에서 정의한 바와 같습니다.
    전자 메일의 경우 다음과 같은 매개 변수를 지정했습니다.

  • 보낸 사람: 보낸 사람 주소

  • 받는 사람: 받는 사람 주소

  • 주제: 주제

  • text: 전자 메일의 텍스트 내용(메일 클라이언트가 HTML을 지원하지 않는 경우)

  • html:
  • 전자메일의 html 내용
    가장 중요한 것은 사용자가 계정을 활성화할 수 있도록 전자 우편에 활성화 링크를 삽입하는 것이다.
    // lib/mailer.js
    module.exports = {
      async sendOptInMail(email, userID, token) {
        let activationLink = `${process.env.BASE_URL}api/verify/${userID}/${token}`;
        let mail = {
          from: process.env.SENDER_MAIL,
          to: email,
          subject: "Please active your account",
          text: `To activate your account, please click this link: ${activationLink}`,
          html: `<p>To activate your account, please click this link: <a href="${activationLink}">${activationLink}</a></p>`,
        };
        await transporter.sendMail(mail);
      },
    };
    
    마지막으로 transporter.sendMail(mail);을 통해 설정된 전자메일을 보냅니다.

    9. 테스트 이중 선택 가입

    All ready! Now you can test your RestAPI. You can use Postman.다시 등록할 수 없는 경우, 로그인할 수 없는 경우, 계정이 확인되지 않은 경우, 링크가 유효한지 확인하려면 시도하십시오.
    하면, 만약, 만약...🙂

    좋은 웹페이지 즐겨찾기