iT邦幫忙

2023 iThome 鐵人賽

DAY 26
0
Security

從自建漏洞中學習 - 一起填坑吧系列 第 26

Auth 應用程式 - Reset passord 篇之 2

  • 分享至 

  • xImage
  •  

Auth 應用程式 - Reset passord 篇之 2

接續上次的 reset password,我們停留在 forgot password 的最後一部分 - 寄送 email。

實作寄送 email

在先前的 forgotPassword function 步驟中,我們做了以下步驟:

  1. 取得 user
  2. 隨機生成 reset token 並儲存

最後,剩下:
3. 將 token 以 email 方式寄出

下載 nodemailer

在 NodeJS,我們可以透過 nodemailer 來寄送 email:
首先,我們需要先 install nodemailer:

npm install nodemailer

實作 email.service.js

接著,我們需要實作一個控管 email 功能的 email.service.js:

email.service.js

const nodemailer = require('nodemailer');

const sendEmail = options => {
    // 建立一個 transporter
    const transporter = nodemailer.createTransport({
        host: process.env.YOUR_EMAIL_HOST,
        port: process.env.YOUR_EMAIL_PORT,
        auth: {
            user: process.env.YOUR_EMAIL_USERNAME,
            pass: process.env.YOUR_EMAIL_PASSWORD
        }
    });
    
    // 定義 email options:
    const mailOptions = {
        from: 'Test <test@test.io>',
        to: options.email,
        subject: options.subject,
        text: options.message,
        html: 
    }
    
    // 最後,寄送 email
    await transporter.sendMail(mailOptions);
}

繼續完成先前的 forgotPassword function

接著,在 forgotPassword function 中,我們傳送 resetPassword 會導向的 url,並放到 message 中:

forgotPassword function :

exports.forgotPassword = catchAsync(async(req, res, next) => {
   // 1. 根據 post 的 email 取得 user
   const user = await User.findOne({ email: req.body.email });
   if (!user) {
       return next(new AppError('There is no user with this email address.', 404));
   }
   
   // 2. 隨機生成 reset token
   const resetToken = user.createTokenForResetPassword();
   // 儲存加密後的 resetToken & 停掉驗證器
   await user.save({ validateBeforeSave: false });
   
   // 此次新加上的內容: 3. 寄送 email
   const resetURL = `${your_url}/${resetToken}`;
   
   const message = `${your_cutom_message} : ${resetURL}`;
   
   // 有可能發生錯誤,所以在這邊加上 try catch
   try {
       await sendEmail({
           email: user.email,
           subject: '您的 password reset token 在 10 mins 中有效',
           message
       });

       res.status(200).json({
           status: 'success',
           message: 'Token was sent through email'
       });
   
   } catch(err) {
       // 若發生 error,則重置 tokenForResetPassword & passwordResetExpiresIn
       this.tokenForResetPassword = undefined;
       this.passwordResetExpiresIn = undefined;
       // 最後保存數據在 DB
       await user.save({ validateBeforeSave: false });
       // 處理 error
       return next(new AppError('Error happened! Please try again later.'), 500);
       
   }
   
});

今日小心得

今天下班回家快點照顧貓貓,邊照顧貓咪邊學習 XD
感覺也是挺不錯的,繼續練習。


Reference


上一篇
Auth 應用程式 - Reset passord 篇之 1
下一篇
Auth 應用程式 - Reset passord 篇之 3
系列文
從自建漏洞中學習 - 一起填坑吧30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言