비밀번호 재설정을 위해 RESTful 리소스를 구성하는 적절한 방법은 무엇입니까?
이 리소스는 비밀번호를 분실하거나 잊어 버린 사람을위한 비밀번호 재설정 도구입니다. 이전 암호를 무효화하고 전자 메일로 암호를 보냅니다.
내가 가진 두 가지 옵션은 다음과 같습니다.
POST /reset_password/{user_name}
또는…
POST /reset_password
-Username passed through request body
요청이 POST 여야한다고 확신합니다. 적절한 이름을 선택했다고 확신하지 못합니다. 그리고 user_name이 URL 또는 요청 본문을 통해 전달되어야하는지 확실하지 않습니다.
답변
업데이트 : (아래에 추가로 설명)
나는 다음과 같이 갈 것입니다.
POST /users/:user_id/reset_password
사용자 모음이 있으며 여기서 단일 사용자는 {user_name}
. 그런 다음 작업 할 작업을 지정합니다 reset_password
. 이 경우에는입니다 . “에 POST
대한 새 reset_password
작업 만들기 ( ) “라고 말하는 것과 같습니다 {user_name}
.
이전 답변 :
나는 다음과 같이 갈 것입니다.
PUT /users/:user_id/attributes/password
-- The "current password" and the "new password" passed through the body
각 사용자에 대한 두 개의 컬렉션, 사용자 컬렉션 및 속성 컬렉션이 있습니다. 사용자는에 의해 지정되고 :user_id
속성은에 의해 지정됩니다 password
. 이 PUT
작업은 컬렉션의 주소가 지정된 구성원을 업데이트합니다.
답변
인증되지 않은 사용자
엔드 포인트 에서 PUT
요청을 수행 api/v1/account/password
하고 사용자가 비밀번호를 재설정 (업데이트)하려는 계정을 식별하기 위해 해당 계정 이메일과 함께 매개 변수가 필요합니다.
PUT : /api/v1/account/password?email={email@example.com}
참고 : 로 @DougDomeny가 URL에 쿼리 문자열로 이메일을 전달하는 그의 코멘트에 언급 된 보안 위험이다. GET 매개 변수는 사용할 때 노출되지 않지만 https
( https
이러한 요청에 대해 항상 적절한 연결을 사용해야 함 ) 관련된 다른 보안 위험이 있습니다. 여기에 있는 이 블로그 게시물 에서이 주제에 대해 자세히 읽을 수 있습니다 .
요청 본문에 이메일을 전달하는 것이 GET 매개 변수로 전달하는 것보다 더 안전한 대안이 될 것입니다.
PUT : /api/v1/account/password
요청 본문 :
{
"email": "email@example.com"
}
응답에는 202
허용 된 응답 의미가 있습니다.
처리를 위해 요청이 수락되었지만 처리가 완료되지 않았습니다. 요청은 처리가 실제로 수행 될 때 허용되지 않을 수 있으므로 결국 처리되거나 처리되지 않을 수 있습니다. 이와 같은 비동기 작업에서 상태 코드를 다시 보낼 수있는 기능은 없습니다.
사용자는에서 이메일을 받게 email@example.com
되며 업데이트 요청 처리 는 이메일 의 링크로 수행 한 작업에 따라 달라집니다.
https://example.com/password-reset?token=1234567890
이 이메일에서 링크를 열면 숨겨진 입력 필드에 대한 입력으로 링크의 비밀번호 재설정 토큰을 사용하는 프런트 엔드 애플리케이션의 비밀번호 재설정 양식으로 연결됩니다 (토큰은 쿼리 문자열로 링크의 일부 임). 다른 입력 필드에서는 사용자가 새 암호를 설정할 수 있습니다. 새 암호를 확인하는 두 번째 입력은 프런트 엔드에서 유효성 검사에 사용됩니다 (오타 방지).
참고 : 이메일에서 사용자가 비밀번호 재설정을 초기화하지 않은 경우 이메일을 무시하고 현재 비밀번호로 애플리케이션을 정상적으로 계속 사용할 수 있다고 언급 할 수도 있습니다.
새 암호와 토큰을 입력으로 사용하여 양식을 제출하면 암호 재설정 프로세스가 수행됩니다. 양식 데이터는 PUT
요청 과 함께 다시 전송 되지만 이번에는 토큰을 포함하여 리소스 비밀번호를 새 값으로 바꿉니다.
PUT : /api/v1/account/password
요청 본문 :
{
"token":"1234567890",
"new":"password"
}
응답은 204
내용 없음 응답이됩니다.
서버가 요청을 수행했지만 엔티티 본문을 반환 할 필요가 없으며 업데이트 된 메타 정보를 반환 할 수 있습니다. 응답은 엔티티 헤더의 형태로 새로운 또는 업데이트 된 메타 정보를 포함 할 수 있으며, 존재하는 경우 요청 된 변형과 연관되어야합니다.
인증 된 사용자
비밀번호를 변경하려는 인증 된 사용자의 PUT
경우 이메일없이 요청을 즉시 수행 할 수 있습니다 (비밀번호를 업데이트하는 계정이 서버에 알려져 있음). 이 경우 양식은 두 개의 필드를 제출합니다.
PUT : /api/v1/account/password
요청 본문 :
{
"old":"password",
"new":"password"
}
답변
잠시 동안 uber-RESTful을 시작하겠습니다. 재설정을 트리거하기 위해 암호에 DELETE 작업을 사용하지 않는 이유는 무엇입니까? 말이되지 않나요? 결국, 당신은 다른 암호를 위해 기존 암호를 효과적으로 버리는 것입니다.
즉, 다음을 수행 할 것입니다.
DELETE /users/{user_name}/password
이제 두 가지 큰주의 사항 :
-
HTTP DELETE는 멱등 적이어야합니다 ( “여러 번 수행하면 별거 아님”이라는 멋진 단어). “비밀번호 재설정”이메일을 보내는 것과 같은 일반적인 작업을 수행하는 경우 문제가 발생합니다. 부울 “Is Reset”플래그를 사용하여 사용자 / 암호에 태그를 지정하는 문제를 해결할 수 있습니다. 삭제할 때마다이 플래그를 확인합니다. 이 설정되어 있지 않은 경우 다음 당신은 암호를 재설정하고 이메일을 보낼 수 있습니다. (이 플래그를 사용하면 다른 용도로도 사용할 수 있습니다.)
-
양식을 통해 HTTP DELETE를 사용할 수 없으므로 AJAX 호출을 수행하거나 POST를 통해 DELETE를 터널링해야합니다.
답변
이메일에 대한 액세스 권한이없는 사용자에 의해 (의도적 또는 의도적으로) 트리거되었을 수 있으므로 초기 요청에서 사용자의 기존 비밀번호를 삭제하거나 파기하고 싶지 않은 경우가 많습니다. 대신 사용자 레코드에서 비밀번호 재설정 토큰을 업데이트하고 이메일에 포함 된 링크로 보냅니다. 링크를 클릭하면 사용자가 토큰을 받았음을 확인하고 암호를 업데이트하기를 원합니다. 이상적으로 이것은 시간에 민감합니다.
이 경우 RESTful 작업은 POST : PasswordResets 컨트롤러에서 생성 작업을 트리거합니다. 액션 자체는 토큰을 업데이트하고 이메일을 보냅니다.
답변
나는 실제로 답을 찾고 있는데, 하나를 제공한다는 의미가 아닙니다. 그러나 “reset_password”는 명사가 아니라 동사이기 때문에 REST 컨텍스트에서 나에게 잘못 들립니다. 이 정당성을 사용하여 “reset action”명사를한다고해도 모든 동사는 명사입니다.
또한 보안 컨텍스트를 통해 사용자 이름을 얻을 수 있고 URL이나 본문을 통해 보낼 필요가 전혀없는 동일한 답변을 검색하는 사람에게는 발생하지 않았을 수 있습니다.
답변
더 나은 아이디어는 다음과 같습니다.
DELETE /api/v1/account/password - To reset the current password (in case user forget the password)
POST /api/v1/account/password - To create new password (if user has reset the password)
PUT /api/v1/account/{userId}/password - To update the password (if user knows is old password and new password)
데이터 제공에 관하여 :
-
현재 비밀번호를 재설정하려면
- 이메일은 본문에 제공되어야합니다.
-
새 암호를 만들려면 (재설정 후)
- 새 비밀번호, 활성화 코드 및 이메일 ID를 본문에 입력해야합니다.
-
비밀번호를 업데이트하려면 (로그인 한 사용자의 경우)
- 이전 암호, 새 암호는 본문에 언급되어야합니다.
- Params의 UserId.
- 헤더의 인증 토큰.
답변
고려해야 할 몇 가지 사항이 있습니다.
비밀번호 재설정은 멱 등성이 아닙니다.
암호 변경은이를 수행하기 위해 자격 증명으로 사용되는 데이터에 영향을 미치므로 저장된 자격 증명이 변경되는 동안 요청이 그대로 반복되는 경우 향후 시도가 무효화 될 수 있습니다. 예를 들어 임시 재설정 토큰을 사용하여 변경을 허용하는 경우 암호를 잊은 상황에서 일반적으로 해당 토큰은 성공적인 암호 변경시 만료되어야하며 요청 복제 시도가 다시 무효화됩니다. 따라서 비밀번호 변경에 대한 RESTful 접근 방식 POST
은 PUT
.
데이터로드시 ID 또는 이메일이 중복 될 수 있음
REST에 위배되지 않고 특별한 목적이있을 수 있지만 비밀번호 재설정을 위해 ID 또는 이메일 주소를 지정할 필요가없는 경우가 많습니다. 생각해보십시오. 인증을 거쳐야하는 요청에 데이터의 일부로 이메일 주소를 제공하는 이유는 무엇입니까? 사용자가 단순히 비밀번호를 변경하는 경우이를 위해 인증해야합니다 (사용자 이름 : 비밀번호, 이메일 : 비밀번호 또는 헤더를 통해 제공된 액세스 토큰을 통해). 따라서 해당 단계에서 해당 계정에 액세스 할 수 있습니다. 비밀번호를 잊어 버린 경우 변경을 수행하기위한 자격 증명으로 사용할 수있는 임시 재설정 토큰 (이메일을 통해)이 제공되었을 것입니다. 그리고이 경우 토큰을 통한 인증은 그들의 계정을 식별하기에 충분해야합니다.
위의 모든 사항을 고려하여 RESTful 암호 변경에 대한 적절한 계획은 다음과 같습니다.
Method: POST
url: /v1/account/password
Access Token (via headers): pwd_rst_token_b3xSw4hR8nKWE1d4iE2s7JawT8bCMsT1EvUQ94aI
data load: {"password": "This 1s My very New Passw0rd"}
