Phone Number
전화번호 플러그인은 사용자가 전화번호를 사용하여 로그인하고 가입할 수 있도록 인증 시스템을 확장합니다. 전화번호를 검증하기 위한 OTP(일회용 비밀번호) 기능이 포함되어 있습니다.
설치
서버에 플러그인 추가
import { betterAuth } from "better-auth"
import { phoneNumber } from "better-auth/plugins"
const auth = betterAuth({
plugins: [
phoneNumber({
sendOTP: ({ phoneNumber, code }, request) => {
// SMS를 통해 OTP 코드 전송 구현
}
})
]
})데이터베이스 마이그레이션
마이그레이션을 실행하거나 스키마를 생성하여 필요한 필드와 테이블을 데이터베이스에 추가합니다.
npx @better-auth/cli migratenpx @better-auth/cli generate필드를 수동으로 추가하려면 Schema 섹션을 참조하세요.
클라이언트 플러그인 추가
import { createAuthClient } from "better-auth/client"
import { phoneNumberClient } from "better-auth/client/plugins"
const authClient = createAuthClient({
plugins: [
phoneNumberClient()
]
})사용법
검증을 위한 OTP 전송
사용자의 전화번호로 검증을 위한 OTP를 전송하려면 sendVerificationCode endpoint를 사용할 수 있습니다.
const { data, error } = await authClient.phoneNumber.sendOtp({ phoneNumber: "+1234567890", // required});| Prop | Description | Type |
|---|---|---|
phoneNumber | OTP를 전송할 전화번호입니다. | string |
전화번호 검증
OTP가 전송된 후 사용자는 코드를 제공하여 전화번호를 검증할 수 있습니다.
const { data, error } = await authClient.phoneNumber.verify({ phoneNumber: "+1234567890", // required code: "123456", // required disableSession: false, updatePhoneNumber: true,});| Prop | Description | Type |
|---|---|---|
phoneNumber | 검증할 전화번호입니다. | string |
code | OTP 코드입니다. | string |
disableSession? | 검증 후 세션 생성을 비활성화합니다. | boolean |
updatePhoneNumber? | 세션이 있는지 확인하고 전화번호를 업데이트합니다. | boolean |
전화번호가 검증되면 사용자 테이블의 phoneNumberVerified 필드가 true로 설정됩니다. disableSession이 true로 설정되지 않으면 사용자를 위한 세션이 생성됩니다. 또한 callbackOnVerification이 제공되면 호출됩니다.
전화번호로 가입 허용
사용자가 전화번호를 사용하여 가입할 수 있도록 하려면 플러그인 구성에 signUpOnVerification 옵션을 전달할 수 있습니다. 사용자를 위한 임시 이메일을 생성하는 getTempEmail 함수를 전달해야 합니다.
export const auth = betterAuth({
plugins: [
phoneNumber({
sendOTP: ({ phoneNumber, code }, request) => {
// SMS를 통해 OTP 코드 전송 구현
},
signUpOnVerification: {
getTempEmail: (phoneNumber) => {
return `${phoneNumber}@my-site.com`
},
//선택적으로, 사용자를 위한 임시 이름을 생성하는 `getTempName` 함수도 전달할 수 있습니다
getTempName: (phoneNumber) => {
return phoneNumber //기본적으로 전화번호를 이름으로 사용합니다
}
}
})
]
})전화번호로 로그인
전송-검증 플로우를 사용하여 사용자를 로그인하는 것 외에도 전화번호를 식별자로 사용하고 전화번호와 비밀번호를 사용하여 사용자를 로그인할 수도 있습니다.
const { data, error } = await authClient.signIn.phoneNumber({ phoneNumber: "+1234567890", // required password, // required rememberMe: true,});| Prop | Description | Type |
|---|---|---|
phoneNumber | 로그인할 전화번호입니다. | string |
password | 로그인에 사용할 비밀번호입니다. | string |
rememberMe? | 세션을 기억합니다. | boolean |
전화번호 업데이트
전화번호 업데이트는 전화번호를 검증하는 것과 동일한 프로세스를 사용합니다. 사용자는 새 전화번호를 검증하기 위한 OTP 코드를 받습니다.
await authClient.phoneNumber.sendOtp({
phoneNumber: "+1234567890" // 새 전화번호
})그런 다음 OTP 코드로 새 전화번호를 검증합니다.
const isVerified = await authClient.phoneNumber.verify({
phoneNumber: "+1234567890",
code: "123456",
updatePhoneNumber: true // 전화번호를 업데이트하려면 true로 설정
})사용자 세션이 존재하면 전화번호가 자동으로 업데이트됩니다.
세션 생성 비활성화
기본적으로 플러그인은 전화번호를 검증한 후 사용자를 위한 세션을 생성합니다. verify 메서드에 disableSession: true를 전달하여 이 동작을 비활성화할 수 있습니다.
const isVerified = await authClient.phoneNumber.verify({
phoneNumber: "+1234567890",
code: "123456",
disableSession: true
})비밀번호 재설정 요청
phoneNumber를 사용하여 비밀번호 재설정 플로우를 시작하려면 클라이언트에서 requestPasswordReset을 호출하여 사용자의 전화번호로 OTP 코드를 전송할 수 있습니다.
const { data, error } = await authClient.phoneNumber.requestPasswordReset({ phoneNumber: "+1234567890", // required});| Prop | Description | Type |
|---|---|---|
phoneNumber | 사용자와 연결된 전화번호입니다. | string |
그런 다음 클라이언트에서 OTP 코드와 새 비밀번호로 resetPassword를 호출하여 비밀번호를 재설정할 수 있습니다.
const { data, error } = await authClient.phoneNumber.resetPassword({ otp: "123456", // required phoneNumber: "+1234567890", // required newPassword: "new-and-secure-password", // required});| Prop | Description | Type |
|---|---|---|
otp | 비밀번호를 재설정할 일회용 비밀번호입니다. | string |
phoneNumber | 비밀번호를 재설정하려는 계정의 전화번호입니다. | string |
newPassword | 새 비밀번호입니다. | string |
옵션
otpLength: 생성할 OTP 코드의 길이입니다. 기본값은6입니다.sendOTP: 사용자의 전화번호로 OTP 코드를 전송하는 함수입니다. 전화번호와 OTP 코드를 인수로 받습니다.expiresIn: OTP 코드가 만료되는 시간(초)입니다. 기본값은300초입니다.callbackOnVerification: 전화번호가 검증된 후 호출되는 함수입니다. 전화번호와 사용자 객체를 첫 번째 인수로, 요청 객체를 두 번째 인수로 받습니다.
export const auth = betterAuth({
plugins: [
phoneNumber({
sendOTP: ({ phoneNumber, code }, request) => {
// SMS를 통해 OTP 코드 전송 구현
},
callbackOnVerification: async ({ phoneNumber, user }, request) => {
// 전화번호 검증 후 콜백 구현
}
})
]
})-
sendPasswordResetOTP: 비밀번호 재설정을 위해 사용자의 전화번호로 OTP 코드를 전송하는 함수입니다. 전화번호와 OTP 코드를 인수로 받습니다. -
phoneNumberValidator: 전화번호를 검증하는 사용자 정의 함수입니다. 전화번호를 인수로 받고 전화번호가 유효한지 여부를 나타내는 부울을 반환합니다. -
signUpOnVerification: 다음 속성을 가진 객체입니다:getTempEmail: 사용자를 위한 임시 이메일을 생성하는 함수입니다. 전화번호를 인수로 받고 임시 이메일을 반환합니다.getTempName: 사용자를 위한 임시 이름을 생성하는 함수입니다. 전화번호를 인수로 받고 임시 이름을 반환합니다.
-
requireVerification: 활성화하면 사용자가 전화번호를 검증할 때까지 전화번호로 로그인할 수 없습니다. 검증되지 않은 사용자가 로그인을 시도하면 서버는 401 오류(PHONE_NUMBER_NOT_VERIFIED)로 응답하고 검증 프로세스를 시작하기 위해 OTP 전송을 자동으로 트리거합니다.
Schema
플러그인은 사용자 테이블에 2개의 필드를 추가해야 합니다
User 테이블
| Field Name | Type | Key | Description |
|---|---|---|---|
| phoneNumber | string | 사용자의 전화번호 | |
| phoneNumberVerified | boolean | 전화번호가 검증되었는지 여부 |
OTP 검증 시도
전화번호 플러그인에는 각 OTP 코드에 대한 검증 시도 횟수를 제한하여 무차별 대입 공격에 대한 내장 보호 기능이 포함되어 있습니다.
phoneNumber({
allowedAttempts: 3, // 기본값은 3입니다
// ... 기타 옵션
})사용자가 허용된 검증 시도 횟수를 초과하면:
- OTP 코드가 자동으로 삭제됩니다
- 추가 검증 시도는 "너무 많은 시도" 메시지와 함께 403 (Forbidden) 상태를 반환합니다
- 사용자는 계속하려면 새 OTP 코드를 요청해야 합니다
시도 횟수를 초과한 후 오류 응답 예제:
{
"error": {
"status": 403,
"message": "너무 많은 시도"
}
}403 상태를 받으면 사용자에게 새 OTP 코드를 요청하도록 안내하세요