최근 PR #43042 변경 이후로, /u/check_username.json은 IP당 분당 10회로 속도 제한이 걸렸습니다.
이로 인해 정상적인 가입 흐름에 회귀(regression) 문제가 발생하는 것으로 보입니다.
새 계정을 생성할 때 Discourse는 사용자 이름 사용 가능 여부를 자동으로 확인합니다. 사용자가 이 한도를 초과하기 위해 양식을 반복적으로 제출할 필요는 없습니다. 단순히 이메일 주소와 사용자 이름을 입력하고, 입력 중 잠시 멈추거나, 사용자 이름을 변경하거나, 수정하는 것만으로도 /u/check_username.json에 대한 여러 요청이 발생할 수 있습니다.
한도에 도달하면 가입 양식에 다음과 같은 메시지가 표시됩니다:
이 작업을 너무 많이 수행했습니다. 나중에 다시 시도해 주세요.
이 오류는 사용자 이름 필드 바로 아래에 표시되며, 속도 제한이 만료될 때까지 사용자가 계속 진행하는 것을 사실상 차단합니다.
사용자가 얼마나 기다려야 하는지에 대한 안내가 없으며, 사용자의 관점에서는 선택한 사용자 이름이나 가입 양식이 고장 난 것처럼 보입니다.
재현 단계
- 익명 사용자로서 가입 양식을 엽니다.
- 유효한 이메일 주소를 입력합니다.
- 사용자 이름을 여러 번 입력하고 수정하며, 변경 사이에 사용자 이름 사용 가능 여부 확인이 실행되도록 합니다.
/u/check_username.json이 1분 이내에 10회 이상 호출될 때까지 계속합니다.- 사용자 이름 필드에 속도 제한 오류가 표시되기 시작합니다:
이 작업을 너무 많이 수행했습니다. 나중에 다시 시도해 주세요.
예상 동작
가입 양식을 완료하거나 수정하는 일반 사용자는 자동 사용자 이름 사용 가능 여부 확인에 의해 트리거되는 내부 속도 제한에 의해 차단되어서는 안 됩니다.
남용 방지를 위해 속도 제한이 필요하더라도, 정상적인 가입 UX는 속도 제한 오류를 노출하거나 계정 생성을 방지하기보다 우아하게(degrade gracefully) 작동해야 합니다.
실제 동작
사용자는 사용자 이름 필드에 인라인 유효성 검사 오류를 받게 되며, 속도 제한이 만료될 때까지 정상적으로 계속 진행할 수 없습니다.
관련 변경 사항
이는 다음에 의해 도입된 것으로 보입니다:
PR #43042 – DEV: IP당 check_username 요청 속도 제한
현재 구현은 다음을 사용합니다:
RateLimiter.new(
current_user,
"check-username-#{request.remote_ip}",
10,
1.minute
).performed!
가입 UI 자체가 여러 사용자 이름 확인을 생성할 수 있으므로, 1분당 10회 요청 제한은 정당한 상호작용 중에 도달할 수 있습니다.
제한기가 세션별로而非 IP별로 적용되는 것이 아니기 때문에, 공유 NAT/공개 IP 주소 뒤에 있는 사용자에게는 더 큰 문제가 될 수도 있습니다.
추가 관찰 사항
check_email에도 IP당 분당 10회의 제한기가 있지만, 이 한도가 초과되면 사용자에게 속도 제한 오류를 표시하는 대신 성공 응답을 반환합니다.
따라서 check_username도 유사하게 작동하는 것이 합리적일 수 있으며, 또는 다음 중 하나가 될 수 있습니다:
-
한도를 증가;
-
구성 가능하게 설정;
-
사용자 이름 제안/자동 유효성 검사 요청을 동일한 버킷에 카운트하지 않음;
-
또는 가입 흐름을 차단하지 않고 클라이언트 측에서 속도 제한을 처리.
PR #43042 변경 이후 https://try.discourse.org/를 포함한 최신 Discourse 설치 환경에서 이 문제를 재현할 수 있습니다.
