Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DMVM-161 feat: SMS 인증, 회원가입 API 구현 #26

Closed
wants to merge 6 commits into from

Conversation

shine-jung
Copy link
Contributor

🎫 161

  • ✨ 새로운 기능 추가

변경 사항에 대한 설명

SMS 인증과, 회원가입 API를 구현했습니다. SMS 전송에는 알리고 API를 사용했습니다.

테스트 방법

API 사용 플로우

  1. SMS 인증 요청:

사용자가 전화번호를 입력하여 인증 코드를 요청합니다.
서버는 해당 전화번호로 SMS 인증 코드를 전송합니다.

POST /v1/auth/request-verification
{
  "phoneNumber": "01012345678"
}
  1. SMS 인증 코드 확인:

사용자가 받은 인증 코드를 서버에 제출하여 인증을 확인합니다.
서버는 인증 코드를 확인하고, 성공 시 verificationId를 반환합니다.

POST /v1/auth/verify-code
{
  "phoneNumber": "01012345678",
  "verificationCode": "123456"
}
  1. 회원 가입:

사용자가 verificationId와 추가 정보를 입력하여 회원가입을 요청합니다.
서버는 전화번호와 verificationId를 확인하고, 새로운 사용자를 등록합니다.

POST /v1/auth/signup
{
  "uuid": "유저 식별자",
  "authProvider": "KAKAO",
  "phoneNumber": "01012345678",
  "verificationId": "verification-id"
}

변경된 환경

변경된 환경(라이브러리 버전, 데이터베이스 스키마 등)에 대한 정보를 제공해주세요.

  • sms_verifications 테이블이 추가되었습니다. 적용된 DDL은 아래와 같습니다.
CREATE TABLE sms_verifications (
    id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
    phone_number VARCHAR(15) NOT NULL,
    verification_code VARCHAR(6) NOT NULL,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    expired_at TIMESTAMP NOT NULL,
    verified_at TIMESTAMP DEFAULT NULL,
    verification_id UUID UNIQUE DEFAULT NULL
);

CREATE INDEX idx_phone_number ON sms_verifications(phone_number);
CREATE INDEX idx_verification_code ON sms_verifications(verification_code);
CREATE INDEX idx_verified_at ON sms_verifications(verified_at);

참고 사항

추후 CustomerService의 create 메서드를 제가 작성한 코드로 교체해야 합니다.
코드 리뷰 부탁드립니다. 감사합니다.

@shine-jung shine-jung requested a review from emibgo2 June 19, 2024 12:19
@shine-jung shine-jung self-assigned this Jun 19, 2024
example: '01012345678',
type: String,
})
phoneNumber: string;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

생각보다 010-1234-5678 이런 패턴으로 입력하시는 분이 많습니다.
정확한 기준을 가지고 정규식으로 특정 패턴의 전화번호만 받는것이 좋을것 같습니다.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

프론트에서 보여지는건 010-0000-0000 이런식이긴합니다.

const newCustomer = await this.customerRepository.create(dto);
return await this.customerRepository.save(newCustomer);
}

async create(dto: CreateCustomerDto): Promise<Customer> {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

모든 정보를 클라이언트에서 수집한 후에 백엔드에선 한번의 Request만으로 처리하는것으로 보이는데 맞나요?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

아래에서 말씀드린것처럼 CRUD 혹은 API마다 DTO가 있는것은
딱히 좋다고 생각들지는 않습니다.
validation이 필요하다고하면 group validation을 지정하여서 하는거는 어떠신가요?

@emibgo2
Copy link
Contributor

emibgo2 commented Aug 13, 2024

  1. 폰번호 저장시에 암호화가 진행되고 있는게 맞을까요?
    제가 확인했을때는 암호화 부분이 보이지 않습니다.

  2. 인증번호는 CachceService를 통해 Redis에 인증번호를 저장하고 TTL로 자동 삭제 되도록 하기로 하지 않았었나요??
    DB를 사용하시는것 같아 여쭈어봅니다.

@shine-jung

@shine-jung
Copy link
Contributor Author

shine-jung commented Aug 19, 2024

  1. 폰번호 저장시에 암호화가 진행되고 있는게 맞을까요?
    제가 확인했을때는 암호화 부분이 보이지 않습니다.
  2. 인증번호는 CachceService를 통해 Redis에 인증번호를 저장하고 TTL로 자동 삭제 되도록 하기로 하지 않았었나요??
    DB를 사용하시는것 같아 여쭈어봅니다.

@shine-jung

두가지 사항 반영했습니다! api 작동이 안되어서 시간이 걸렸네요ㅠㅠ 암호화 알고리즘은 AES256 CTR 사용했습니다. 시간되실 때 확인 부탁드립니다!

@shine-jung shine-jung requested a review from emibgo2 August 19, 2024 14:56
import { EncryptionServiceInterface } from '../domain/encryption-service.interface';

@Injectable()
export class EncryptionService implements EncryptionServiceInterface {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

EncryptionServiceInterface라는 이름보단 IEncryptionService가 어떨까요?

private readonly ivLength = 16;

constructor(private readonly configService: ConfigService) {
this.secretKey = this.configService.get<string>('encryption.secretKey');
Copy link
Contributor

@emibgo2 emibgo2 Aug 21, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Parameter Store의 계층구조에 따라 encryption.secretKey보단
encryption/secretKey나 encryption/key/secret가 좋아보입니다.

'sms/expired_minutes',
10,
);
this.otpLength = this.configService.get<number>('sms/otp_length', 6);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

camelCase, snakeCase 둘다 혼용되고 있는것 같은데 맞춰주세요
그리고 위에서 설명드린것처럼 계층구조로 나타내는것은 어떤지 고민해봐주세요

const customer = this.customerRepository.create({
uuid: dto.uuid,
customerName: dto.name,
customerPhoneNumber: dto.phoneNumber,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

아직 phoneNumber가 DB저장시 암호화 되지 않는걸로 확인됩니다.
확인 부탁드려요

customerPhoneNumber: dto.phoneNumber,
customerLocation: null,
authProvider: dto.authProvider,
createdAt: new Date(),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

createdAt은 CreateDateColumn로 선언되어 있어서 해당 코드가 필요 없어보입니다.

customerLocation: null,
authProvider: dto.authProvider,
createdAt: new Date(),
modifiedAt: new Date(),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

UpdateDateColumn이어서 필요없지 않나라는 의문점입니다.

@emibgo2 emibgo2 closed this Feb 27, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants