Skip to content

2. Login dan Register

Pada bahasan kali kita kita akan membuat feature untuk authentikasi pada project kita. Kita akan belajar langkah demi langkah untuk membuat authentikasi.

Membuat module auth

terminal
npx nest c module  app/auth
npx nest g controller  app/auth
npx nest g service   app/auth
Alt text

Pada project ini, semua module feature kita masukan ke dalam folder app seperi pada gambar di atas

Membuat Entity

Alt text

Pada project kita table user seperti pada gambar di atas. Selanjutnya kita akan membuat entity pada module auth

auth.entity.ts
import { Entity, BaseEntity, PrimaryGeneratedColumn, Column } from "typeorm";

@Entity()
export class User extends BaseEntity {
  @PrimaryGeneratedColumn()
  id: number;

  @Column({ nullable: true })
  avatar: string;

  @Column({ nullable: false })
  nama: string;

  @Column({ unique: true, nullable: false })
  email: string;

  @Column({ nullable: true })
  password: string;

  @Column({ nullable: true })
  refresh_token: string;

  @Column({ nullable: true })
  role: string;

  @Column({ type: "datetime", default: () => "CURRENT_TIMESTAMP" })
  created_at: Date;

  @Column({ type: "datetime", default: () => "CURRENT_TIMESTAMP" })
  updated_at: Date;
}

Implementasikan pada module

auth.module.ts

auth.module.ts
import { Module } from "@nestjs/common";
import { AuthController } from "./auth.controller";
import { AuthService } from "./auth.service";
import { TypeOrmModule } from "@nestjs/typeorm";
import { User } from "./auth.entity";

@Module({
  imports: [TypeOrmModule.forFeature([User])],
  controllers: [AuthController],
  providers: [AuthService],
})
export class AuthModule {}

Membuat fitur Register

Membuat DTO untuk register

auth.dto.ts
import { PartialType, PickType } from "@nestjs/mapped-types";
import { IsEmail, IsInt, IsString, Length, MinLength } from "class-validator";

export class UserDto {
  @IsInt()
  id: number;

  @IsString()
  nama: string;

  @IsString()
  avatar: string;

  @IsString()
  @IsEmail()
  email: string;

  @IsString()
  @MinLength(8)
  password: string;

  @IsString()
  refresh_token: string;

  @IsString()
  role: string;
}

export class RegisterDto extends PickType(UserDto, [
  "nama",
  "email",
  "password",
]) {}

Instalasi package crypto untuk hash password

terminal
npm install bcrypt --save
npm install -D @types/bcrypt

Membuat Service untuk register

auth.service.ts
import { HttpException, HttpStatus, Injectable } from "@nestjs/common";
import { InjectRepository } from "@nestjs/typeorm";
import BaseResponse from "src/utils/response/base.response";
import { User } from "./auth.entity";
import { Repository } from "typeorm";
import { ResponseSuccess } from "src/interface/response";
import { RegisterDto } from "./auth.dto";
import { hash } from "bcrypt"; //import hash

@Injectable()
export class AuthService extends BaseResponse {
  constructor(
    @InjectRepository(User) private readonly authRepository: Repository<User>
  ) {
    super();
  }

  async register(payload: RegisterDto): Promise<ResponseSuccess> {
    const checkUserExists = await this.authRepository.findOne({
      where: {
        email: payload.email,
      },
    });
    if (checkUserExists) {
      throw new HttpException("User already registered", HttpStatus.FOUND);
    }

    payload.password = await hash(payload.password, 12); //hash password
    await this.authRepository.save(payload);

    return this._success("Register Berhasil");
  }
}

Membuat Controller untuk end point register

auth.controller.ts
import { Controller, Post, Body } from "@nestjs/common";
import { RegisterDto } from "./auth.dto";
import { AuthService } from "./auth.service";

@Controller("auth")
export class AuthController {
  constructor(private authService: AuthService) {}
  @Post("register")
  async register(@Body() payload: RegisterDto) {
    return this.authService.register(payload);
  }
}

Pengujian di Postman

Alt text

payload
{
    "nama" : "ihsan santana w",
    "email" :"ihsanabuhanifah@gmail.com",
    "password" : "12345678"
}

Cek Pada table users di database

Alt text

Terlihat pada gambar di atas, kita sudah berhasil register user baru dan passowrd berhasil di hash.

Membuat Fitur Login

Sebelumnya kita sudah berhasil membuat fitur register , selanjutnya kita akan membuat fitur login.

Membuat Login DTO

auth.dto.ts

import { PartialType, PickType } from '@nestjs/mapped-types';
import { IsEmail, IsInt, IsString, Length, MinLength } from 'class-validator';

...

export class LoginDto extends PickType(UserDto, ['email', 'password']) {}

Membuat Service untuk login

auth.service.ts
 async login(payload: LoginDto): Promise<ResponseSuccess> {
    const checkUserExists = await this.authRepository.findOne({
      where: {
        email: payload.email,
      },
      select: {
        id: true,
        nama: true,
        email: true,
        password: true,
        refresh_token: true,
      },
    });

    if (!checkUserExists) {
      throw new HttpException(
        'User tidak ditemukan',
        HttpStatus.UNPROCESSABLE_ENTITY,
      );
    }

    const checkPassword = await compare(
      payload.password,
      checkUserExists.password,
    ); // compare password yang dikirim dengan password yang ada di tabel
    if (checkPassword) {
      return this._success('Login Success', checkUserExists);
    } else {
      throw new HttpException(
        'email dan password tidak sama',
        HttpStatus.UNPROCESSABLE_ENTITY,
      );
    }
  }

Membuat end point login pada controller

@Post('login')
  async login(@Body() payload: LoginDto) {
    return this.authService.login(payload);
  }

Pengujian pada Postman

Alt text

payload
{
    "email" :"ihsanabuhanifah@gmail.com",
    "password" : "12345678"
}