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
Pada project ini, semua module feature kita masukan ke dalam folder app seperi pada gambar di atas
Membuat Entity
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
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
payload
{
"nama" : "ihsan santana w",
"email" :"ihsanabuhanifah@gmail.com",
"password" : "12345678"
}
Cek Pada table users di database
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,
);
}
}