0
0
Lập trình
Hưng Nguyễn Xuân 1
Hưng Nguyễn Xuân 1xuanhungptithcm

Hướng dẫn chi tiết triển khai chức năng quên mật khẩu trong NestJS 9 với Nodemailer

Đăng vào 3 tuần trước

• 5 phút đọc

Chủ đề:

@reactjs

Hướng dẫn triển khai chức năng quên mật khẩu trong NestJS 9 sử dụng Nodemailer

Tóm tắt

Bài viết này sẽ hướng dẫn bạn cách xây dựng chức năng quên mật khẩu trong ứng dụng NestJS, sử dụng Nodemailer để gửi email và Handlebars để tạo template email. Chúng ta sẽ từng bước thực hiện từ cài đặt đến triển khai chi tiết.

Mục tiêu

  • Cài đặt và cấu hình Nodemailer và Handlebars.
  • Tạo dịch vụ gửi email cho ứng dụng.
  • Tạo module và service để quản lý nhiều loại email.
  • Triển khai chức năng quên mật khẩu trong Auth Controller.
  • Tạo template email sử dụng Handlebars.

1. Cài đặt các thư viện cần thiết

Đầu tiên, bạn cần cài đặt hai thư viện Nodemailer và Handlebars. Mở terminal và chạy các lệnh sau:

Copy
npm install nodemailer
npm install handlebars

2. Cấu hình Nodemailer

Tiếp theo, bạn cần cấu hình Nodemailer để gửi email. Tạo một file mailer.service.ts với nội dung sau:

typescript Copy
import { Injectable } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import nodemailer from 'nodemailer';
import Handlebars from 'handlebars';
import fs from 'node:fs/promises';

@Injectable()
export class MailerService {
  private readonly transporter: nodemailer.Transporter;

  constructor(private readonly configService: ConfigService) {
    this.transporter = nodemailer.createTransport({
      host: configService.get<string>('mailer.host', { infer: true }),
      port: configService.get<number>('mailer.port', { infer: true }),
      secure: configService.get<boolean>('mailer.secure', { infer: true }),
      auth: {
        user: configService.get<string>('mailer.user', { infer: true }),
        pass: configService.get<string>('mailer.password', { infer: true }),
      },
      debug: true,
    });
  }

  async sendMail({
    templatePath,
    context,
    ...mailOptions
  }: nodemailer.SendMailOptions & {
    templatePath: string;
    context: Record<string, unknown>;
  }): Promise<void> {
    let html: string | undefined;
    if (templatePath) {
      const template = await fs.readFile(templatePath, 'utf-8');
      html = Handlebars.compile(template, { strict: true })(context);
    }

    await this.transporter.sendMail({
      ...mailOptions,
      from: mailOptions.from
        ? mailOptions.from
        : `"${this.configService.get<string>('mailer.defaultName', { infer: true })}" <${this.configService.get<string>('mailer.defaultEmail', { infer: true })}>`,
      html: mailOptions.html ? mailOptions.html : html,
    });
  }
}

Giải thích từng phần

  • nodemailer.createTransport: Dùng để tạo một transporter nhằm gửi email.
  • sendMail: Hàm này kết hợp Handlebars để biên dịch template email và gửi đi.

3. Cấu hình file .env

Thêm các thông tin cấu hình cần thiết vào file .env của bạn:

Copy
MAILER_HOST=smtp.gmail.com
MAILER_PORT=587
MAILER_USER=your-email@gmail.com
MAILER_PASSWORD=your-email-password
MAILER_SECURE=false
MAILER_DEFAULT_NAME=Your Name
MAILER_DEFAULT_EMAIL=your-email@gmail.com

4. Tạo module Mailer

Tiếp theo, bạn tạo một module để chứa MailerService. Tạo file mailer.module.ts và điền nội dung phù hợp.

5. Import MailerModule vào AppModule

Bạn cần import MailerModule vào AppModule để có thể sử dụng nó trong toàn ứng dụng:

typescript Copy
import { Module } from '@nestjs/common';
import { ConfigModule } from '@nestjs/config';
import { MailerModule } from './mailer/mailer.module';
import { AuthModule } from './auth/auth.module';

@Module({
  imports: [
    ConfigModule.forRoot({
      isGlobal: true,
    }),
    MailerModule,
    AuthModule,
  ],
  controllers: [],
  providers: [],
})
export class AppModule {}

6. Tạo chức năng quên mật khẩu trong Auth Controller

Tiếp theo, tạo file auth.controller.ts với nội dung sau:

typescript Copy
import { Controller, Post, Body } from '@nestjs/common';
import { AuthService } from './auth.service';
import { ForgotPasswordDto } from './dto/forgot-password.dto';

@Controller('auth')
export class AuthController {
  constructor(private readonly authService: AuthService) {}

  @Post('forgot-password')
  async forgotPassword(@Body() forgotPasswordDto: ForgotPasswordDto) {
    return this.authService.forgotPassword(forgotPasswordDto);
  }
}

Sau đó, tạo service để xử lý chức năng quên mật khẩu. Tạo file auth.service.ts với nội dung như sau:

typescript Copy
import { Injectable } from '@nestjs/common';
import { MailsService } from 'src/mails/mails.service';
import { ForgotPasswordDto } from './dto/forgot-password.dto';

@Injectable()
export class AuthService {
  constructor(private readonly mailsService: MailsService) {}

  async forgotPassword(forgotPasswordDto: ForgotPasswordDto) {
    const { email, userName, token } = forgotPasswordDto;

    await this.mailsService.forgotPassword({
      to: email,
      data: {
        token,
        user_name: userName,
      },
    });

    return { message: 'Email đặt lại mật khẩu đã được gửi.' };
  }
}

7. Tạo module MailsService

Bạn cần tạo một module để quản lý và gửi các loại email như quên mật khẩu, xác thực, v.v. Tạo file mails.service.ts với nội dung như sau:

typescript Copy
import { Injectable } from '@nestjs/common';
import path from 'path';
import { ConfigService } from '@nestjs/config';
import { MailerService } from 'src/mailer/mailer.service';

@Injectable()
export class MailsService {
  constructor(
    private readonly mailerService: MailerService,
    private readonly configService: ConfigService,
  ) {}

  async forgotPassword(mailData: {
    to: string;
    data: {
      token: string;
      user_name: string;
    };
  }): Promise<void> {
    await this.mailerService.sendMail({
      to: mailData.to,
      subject: 'Đặt lại mật khẩu',
      templatePath: path.join(
        this.configService.get<string>('mailer.workingDirectory', {
          infer: true,
        }),
        'src',
        'mails',
        'templates',
        'reset-password.hbs',
      ),
      context: {
        username: mailData.data.user_name,
        resetLink: `${this.configService.get<string>('app.clientURL')}/reset-password?token=${mailData.data.token}`,
      },
    });
  }
}

8. Kết luận

Qua bài viết này, bạn đã học cách triển khai chức năng quên mật khẩu trong ứng dụng NestJS bằng cách sử dụng Nodemailer và Handlebars. Chức năng này sẽ tự động gửi email đến người dùng với liên kết để họ có thể đặt lại mật khẩu của mình. Bạn có thể tùy chỉnh thêm nội dung và giao diện email theo nhu cầu của dự án. Chúc bạn thành công trong việc triển khai chức năng này!

source: viblo

Gợi ý câu hỏi phỏng vấn
Không có dữ liệu

Không có dữ liệu

Bài viết được đề xuất
Bài viết cùng tác giả

Bình luận

Chưa có bình luận nào

Chưa có bình luận nào