지난 포스트에서 알리고 API를 통해 문자를 보내는 예제를 구현했었다.
이번 포스트에서는 알리고 API를 사용한 로그인/회원가입 기능을 구현해보려고 한다.
👉 인증 코드 보내기
class SendCodeService {
constructor({ AuthCode }) {
this.AuthCode = AuthCode
}
async sendAligo(phoneNum) {
// 인증 코드 생성
const authCode = generateAuthCode()
// 국제 번호로 요청된 전화번호를 010 형식으로 바꾸기
const convertedPhoneNum = await convertPhoneNum(phoneNum)
const body = {
key: process.env.ALIGO_API_KEY, // 알리고 API 키
user_id: process.env.ALIGO_USER_ID, // 알리고 유저 아이디
sender: process.env.SENDER, // 인증코드를 보내는 번호
receiver: convertedPhoneNum, // 인증코드를 받는 번호
msg: `[일손(ilson)] 인증 번호 [${authCode}]를 입력해주세요.`, // 보낼 문자 내용
msg_type: "SMS", // 메세지 유형
testmode_yn: "Y", // 테스트모드 Y/N
}
try {
const response = await axios.post(
"https://apis.aligo.in/send/",
qs.stringify(body),
{
headers: {
"Content-Type": "application/x-www-form-urlencoded", // 헤더 content-type 설정
},
}
)
const resData = response.data
if (resData.result_code === "1") {
// 인증에 성공하면 해당 전화번호의 인증코드를 삭제
await this.AuthCode.deleteMany({ phone_number: phoneNum })
// 유효 시간
const expirationTime = new Date(Date.now() + 10 * 60 * 1000)
// 인증 코드를 전화번호와 함께 저장
await new this.AuthCode({
phone_number: phoneNum.toString(),
auth_code: authCode.toString(),
expiration_time: expirationTime,
}).save()
return true
} else {
throw new Error(resData.message)
}
} catch (err) {
throw err
}
}
}
export default SendCodeService
인증코드를 보내는 서비스 로직이다.
알리고 서비스에서 필수로 요구하는 값들을 body에 저장해서 application/x-www-form-urlencoded 형식으로 변환한 뒤 POST 요청을 보낸다. 인증에 성공하면 이전 인증코드를 모두 삭제하고 유효 시간을 설정한 뒤 전화번호와 함께 인증코드를 저장한다.
👉 인증코드 검증하기
async verifyAuthCode({ phoneNum, inputCode }) {
try {
const storedAuthCode = await AuthCode.findOne({
phone_number: phoneNum.toString(),
}).sort({ createdAt: -1 })
if (
storedAuthCode === null ||
new Date() > storedAuthCode.expiration_time
) {
await AuthCode.deleteMany({ phone_number: phoneNum }) // 만료된 인증코드 삭제
throw new Error("인증 코드가 만료되었거나 존재하지 않습니다.")
}
if (inputCode.toString() !== storedAuthCode.auth_code.toString()) {
throw new Error("인증 코드가 잘못되었습니다.")
}
// 인증 성공 후 관련 인증코드 모두 삭제
await AuthCode.deleteMany({ phone_number: phoneNum })
return true
} catch (err) {
throw new Error()
}
}
저장해뒀던 인증코드를 가져온다. 인증코드가 만료되었거나 존재하지 않거나, 일치하지 않는다면 에러를 반환한다. 인증코드를 서로 비교할 때 .toString()으로 비교해주지 않으면 에러가 났던 걸로 기억한다.. 인증 성공 후에는 관련 인증코드를 모두 삭제한다.
👉 회원가입 하기
async signup({ country, phoneNum, inputCode, username, profileImg, intro }) {
try {
// 인증코드가 만료, 존재, 오류 여부 확인하기
const isChecked = await this.verifyAuthCode({ phoneNum, inputCode })
if (!isChecked) {
throw new Error("인증 실패")
}
// 인증코드와 함께 유저 정보 저장하기
const newUser = await new User({
country,
phoneNum,
inputCode,
username,
profileImg,
intro,
}).save()
return newUser
} catch (err) {
throw new Error("회원가입 중 오류 발생")
}
}
👉 로그인 하기
async login({ phoneNum, inputCode }) {
try {
const isChecked = await this.verifyAuthCode({ phoneNum, inputCode })
if (!isChecked) {
throw new Error(err.message)
}
const user = await User.findOne({ phoneNum })
if (!user) {
throw new Error("일치하는 유저가 없음")
}
const payload = {
userId: user._id,
phoneNum: user.phoneNum,
inputCode: user.inputCode,
}
// 토큰 발급
const token = generateToken(payload)
return { message: "로그인 성공", token }
} catch (err) {
throw new Error(err.message || "로그인 중 오류 발생")
}
}

감사합니다 (●ˇ∀ˇ●)
'Development > Back-end' 카테고리의 다른 글
| [Socket.io] Socket.io 에 대하여 (0) | 2025.06.07 |
|---|---|
| [Express] 좋아요 기능 구현하기 (0) | 2025.06.06 |
| [Express] 알리고 API 를 이용한 문자 서비스 예제 (0) | 2025.05.19 |
| [Express] 게시글 관리 미들웨어 (express-validator) (0) | 2025.05.07 |
| [Express] 유저 인증 미들웨어 (0) | 2025.05.07 |