고객

비밀번호

변경하면 모든 기기에서 다시 로그인해요.

v1 API 상세: 회원

로그인한 회원이 바꾸는 비밀번호 변경​​과, 로그아웃 상태에서 연락처 인증으로 다시 설정하는 비밀번호 찾기​​예요. 두 경로 모두 성공하면 그 회원의 기존 세션이 전부 끊겨요.

비밀번호 변경

로그인한 회원이 현재 비밀번호를 확인한 뒤 새 비밀번호를 설정해요.

PUThttps://api.bootapi.com/v1/users/me/password[Basic Auth](/server/authentication) + `Bootpay-User-JWT` 또는 가맹점 서버의 `user_id`

필요 권한: user:user_me_password_update

파라미터 타입 필수 설명
user_id String 선택 회원 ID 또는 가맹점 회원 고유 ID(external_uid). secretKey 인증에서만 허용해요
current_password String 필수 현재 비밀번호
new_password String 필수 새 비밀번호 (8자 이상, 72바이트 이하)
new_password_confirmation String 선택 새 비밀번호 확인. 보내면 서버가 일치를 확인해요

JWT를 보내면 회원은 그 세션으로 정해져요. JWT 없이 user_id를 보내면 가맹점 서버가 지정한 회원을 대상으로 하므로, 쇼핑몰 서버에서 먼저 본인임을 확인해야 해요. 둘을 함께 보내고 다른 회원을 가리키면 403 USER_NOT_MATCH예요.

응답은 { "changed": true, "requires_login": true } 예요.

변경하면 모든 기기에서 로그아웃돼요

비밀번호가 바뀌면 변경 전에 발급된 고객 JWT 가 전부 무효​​가 돼요. 요청을 보낸 그 기기의 JWT 도 포함이에요. 응답의 requires_login: true 가 그 신호이니, BFF 는 성공 응답을 받으면 세션 쿠키를 지우고 로그인 화면으로 보내요. 이 처리를 하지 않으면 다음 회원 API 요청이 401 로 떨어져요.

같은 동작이 쇼핑몰 마이페이지의 비밀번호 변경에도 적용돼요.

비밀번호 규칙

가입·변경·재설정이 같은 규칙을 써요.

  • 8자 이상
  • 72바이트 이하 — BCrypt 가 72바이트 뒤를 버리기 때문이에요. 한글은 한 글자가 3바이트라 24자까지예요.
  • 앞뒤 공백은 서버가 제거한 뒤 저장해요.
  • 현재 비밀번호와 같은 값으로는 바꿀 수 없어요.

오류

error_code 상황
USER_SESSION_INVALID (420) JWT 누락·만료·로그아웃·탈퇴·다른 프로젝트 세션
USER_JWT_INVALID (419) 서명 위조·변조·exp 경과
USER_PASSWORD_NOT_SET (10803) 비밀번호가 없는 소셜 전용 계정 — 비밀번호 찾기로 설정해요
USER_LOGIN_PASSWORD_NOT_MATCH (416) 현재 비밀번호 불일치
USER_PASSWORD_FORMAT_INVALID (475) 8자 미만이거나 현재와 같은 비밀번호
CUSTOMER_FIELD_TOO_LONG 72바이트 초과 (payload.max_length: 72)
USER_PASSWORD_CONFIRM_NOT_MATCH (474) 확인 입력 불일치

현재 비밀번호가 틀리면 새 비밀번호 판정을 하지 않고 먼저 거절해요. 검증에서 걸린 요청은 비밀번호도 세션도 바꾸지 않아요.

비밀번호 찾기

로그아웃한 회원이 등록된 연락처​​로 인증을 마친 뒤에만 새 비밀번호를 설정해요. 세 단계예요.

수신처를 지정할 수 없어요

인증코드는 언제나 상점에 등록된 그 회원의 연락처로 가요. 요청에 email·phone·contact를 넣으면 조용히 무시하지 않고 거절해요. 요청자가 수신처를 바꿀 수 있으면 계정 탈취 경로가 되기 때문이에요.

1단계 — 인증코드 발송

POSThttps://api.bootapi.com/v1/users/password-recovery/requestsBasic Auth

필요 권한: user:user_password_recovery · 고객 JWT는 필요 없어요.

파라미터 타입 필수 설명
login_id String 필수 로그인 아이디 (이메일 가입 상점은 이메일)
channel String 필수 email 또는 phone
{ "accepted": true, "retry_after": 60, "challenge_id": "9f2c1a7e4b83d05c6a1f..." }json

계정이 없어도 같은 모양으로 응답해요. 쿨다운에 걸렸을 때도, 발송이 실패했을 때도 같아요. 응답으로 계정 존재 여부를 알 수 없게 하기 위해서예요. 그래서 화면에는 "가입된 연락처로 인증코드를 보냈어요"처럼 존재를 단정하지 않는 문구를 써요.

발송은 60초에 한 번​​이에요.

2단계 — 인증코드 확인

POSThttps://api.bootapi.com/v1/users/password-recovery/verificationsBasic Auth
파라미터 타입 필수 설명
challenge_id String 필수 1단계 응답의 값
code String 필수 받은 인증코드
{ "reset_token": "eyJhbGciOi...", "expires_at": "2026-09-21T10:10:00+09:00" }json

인증코드는 3분 안에 입력해야 하고, 5회 틀리면 그 challenge는 막혀요. 다시 1단계부터 시작해요.

3단계 — 새 비밀번호 설정

PUThttps://api.bootapi.com/v1/users/password-recovery/passwordBasic Auth
파라미터 타입 필수 설명
reset_token String 필수 2단계 응답의 일회성 토큰
new_password String 필수 새 비밀번호 (변경과 같은 규칙)
new_password_confirmation String 필수 새 비밀번호 확인

login_id를 받지 않아요. 회원은 reset_token이 정해요.

{ "changed": true, "requires_login": true }json

reset_token은 한 번만 쓸 수 있어요. 같은 토큰으로 다시 호출하면 410이에요. 동시에 두 번 들어와도 한 번만 성공해요.

토큰은 발급한 상점·용도·회원·challenge가 모두 맞아야 통과해요. 다른 상점의 토큰이나 다른 용도로 만든 토큰은 거절돼요.

비밀번호 찾기 오류

error_code HTTP 상황
API_PARAM_INVALID 400 email·phone·contact 를 보냄, channel 이 email/phone 이 아님
VERIFICATION_CODE_EXPIRED (471) 400 인증코드 만료, 없는 challenge_id, 다른 상점의 challenge
VERIFICATION_ATTEMPT_EXCEEDED (472) 400 인증코드 5회 초과
FIND_PASSWORD_RESET_TOKEN_INVALID (467) 401 상점·용도·회원·challenge 불일치
FIND_PASSWORD_RESET_TOKEN_EXPIRED (469) 400 토큰 서명 오류·만료
FIND_PASSWORD_RESET_TOKEN_USED (10804) 410 이미 사용한 토큰
USER_PASSWORD_CONFIRM_NOT_MATCH (474) 400 확인 입력 불일치

없는 challenge_id와 만료된 challenge_id가 같은 오류로 나가요 — 존재 여부를 구분하지 않기 위해서예요.

쇼핑몰 내부 경로와의 차이

Bootpay 호스팅 쇼핑몰이 쓰는 /mall/user/find-password/*는 상점 세션으로 동작하는 내부 경로라 외부 쇼핑몰에서는 쓸 수 없어요. 위 v1 경로가 같은 도메인 정책 위에서 공개 계약만 다시 정의한 것이에요.