Reposant réinitialisation de mot de passe

Quelle est la bonne façon de structurer une ressource RESTful pour réinitialiser un mot de passe?

cette ressource se veut un reseteur de mot de passe pour quelqu'un qui a perdu ou oublié son mot de passe. Il invalide leur ancien mot de passe et leur envoie par e-mail un mot de passe.

les deux options que j'AI sont:

POST /reset_password/{user_name}

ou...

POST /reset_password
   -Username passed through request body

je suis presque sûr que la demande devrait être un POST. Je suis de moins en moins confiant que j'ai choisi un nom approprié. Et je ne suis pas sûr si le nom d'utilisateur doit être passé par L'URL ou le corps de la requête.

76
demandé sur Darrel Miller 2010-06-20 01:06:17

9 réponses

mise à jour: (suite au commentaire ci-dessous)

je voudrais aller quelque chose comme ceci:

POST /users/:user_id/reset_password

vous avez une collection d'utilisateurs, où l'utilisateur unique est spécifié par le {user_name} . Vous spécifiez alors l'action à utiliser, qui dans ce cas est reset_password . C'est comme dire "créer ( POST ) un nouveau reset_password action pour {user_name} ".


précédente réponse:

je voudrais aller quelque chose comme ceci:

PUT /users/:user_id/attributes/password
    -- The "current password" and the "new password" passed through the body

vous auriez deux collections, une collection d'utilisateurs, et une collection d'attributs pour chaque utilisateur. L'utilisateur est spécifié par le :user_id et l'attribut est spécifié par password . L'opération PUT met à jour le membre adressé de la collection.

45
répondu Daniel Vassallo 2017-02-10 04:11:59

utilisateurs non authentifiés

nous faisons une PUT demande sur un api/v1/account/password endpoint et exiger un paramètre avec le compte correspondant email pour identifier le compte pour lequel l'utilisateur veut réinitialiser (mettre à jour) le mot de passe:

PUT : /api/v1/account/password?email={email@example.com}

Note: comme @DougDomeny mentionné dans son commentaire passer l'email comme une chaîne de requête dans l'url est un risque de sécurité. OBTENIR les paramètres ne sont pas exposés lors de l'utilisation de https (et vous devez toujours utiliser une connexion https appropriée pour de telles requêtes), mais il y a d'autres risques de sécurité impliqués. Vous pouvez lire plus sur ce sujet dans ce billet de blog ici .

passer l'email dans le corps serait une alternative plus sûre à passer comme param obtenir:

PUT : /api/v1/account/password

data : {
    "email": "email@example.com"
}

la réponse a un 202 accepté réponse:

la demande a été acceptée pour traitement, mais le traitement n'est pas terminé. Il se peut qu'on ne donne pas suite à la demande, car elle peut être rejetée lorsque le traitement a effectivement lieu. Il n'est pas possible de réémettre un code d'État à partir d'une opération asynchrone comme celle-ci.

l'Utilisateur recevra un email à email@example.com et le traitement de la demande de mise à jour dépend des actions prises avec le lien dans le courriel. Le courriel contient un lien vers un formulaire de mot de passe réinitialisé avec un jeton de mot de passe réinitialisé comme chaîne de requête.

lorsque le formulaire est soumis avec un nouveau mot de passe et le token comme entrées, le processus de réinitialisation du mot de passe aura lieu. Les données du formulaire seront envoyées avec une nouvelle demande PUT mais cette fois-ci incluant le token et nous remplacerons le mot de passe ressource par une nouvelle valeur:

PUT : /api/v1/account/password

data : {
    "token":"1234567890",
    "new":"password"
}

La réponse sera un 204 aucun contenu réponse

le serveur a répondu à la requête mais n'a pas besoin de renvoyer un corps d'entité, et pourrait vouloir renvoyer des informations mises à jour. La réponse peut inclure des métadonnées nouvelles ou mises à jour sous la forme d'en-têtes d'entités qui, le cas échéant, doivent être associés à la variante demandée.

utilisateurs authentifiés

pour les utilisateurs authentifiés qui veulent changer leur mot de passe, la requête PUT peut être effectuée immédiatement sans l'e-mail (le compte pour lequel nous mettons à jour le mot de passe est connu du serveur). Dans ce cas, le formulaire comporte deux champs:

PUT : /api/v1/account/password

data : {
    "old":"password",
    "new":"password"
}
45
répondu Wilt 2018-07-04 17:09:42

reposons-nous une seconde. Pourquoi ne pas utiliser L'action Supprimer pour le mot de passe pour déclencher une réinitialisation? De sens, n'est-ce pas? Après tout, vous rejetez effectivement le mot de passe existant en faveur d'un autre.

ça veut dire que tu ferais:

DELETE /users/{user_name}/password

maintenant, deux grandes mises en garde:

  1. HTTP DELETE est censé être idempotent (un mot fantaisiste pour dire " pas grand si vous le faites plusieurs fois"). Si vous faites le truc standard comme envoyer un email de "réinitialisation du mot de passe", alors vous allez rencontrer des problèmes. Vous pouvez travailler autour de cette étiquette l'utilisateur/mot de passe avec un drapeau booléen "is Reset". Sur chaque supprimer, vous vérifiez ce drapeau; si ce n'est pas défini puis vous pouvez réinitialiser le mot de passe et envoyer votre e-mail. (Notez que ce drapeau peut avoir d'autres usages.)

  2. Vous ne pouvez pas utiliser HTTP DELETE via un formulaire , donc vous devrez faire un appel AJAX et/ou tunnel la suppression à travers le POST.

15
répondu Craig Walker 2017-05-23 12:18:14

souvent, vous ne voulez pas supprimer ou détruire le mot de passe existant de l'utilisateur sur la demande initiale, car cela peut avoir été déclenché (involontairement ou intentionnellement) par un utilisateur qui n'a pas accès à l'e-mail. Au lieu de cela, mettez à jour un jeton de mot de passe réinitialisé sur l'enregistrement de l'utilisateur et envoyez-le dans un lien inclus dans un e-mail. Cliquer sur le lien confirmerait que l'Utilisateur a reçu le token et souhaite mettre à jour son mot de passe. Idéalement, ce serait le temps sensible.

l'action RESTful dans ce cas serait un POST: déclenchant l'action create sur le contrôleur PasswordResets. L'action elle-même mettrait à jour le token et enverrait un e-mail.

11
répondu Mark Swardstrom 2013-01-28 20:59:18

en fait, je cherche une réponse, sans vouloir en donner une - mais" reset_password " sonne faux pour moi dans un contexte de repos parce que c'est un verbe, pas un nom. Même si vous dites que vous faites un nom "reset action" - en utilisant cette justification, tous les verbes sont des noms.

en outre, il se peut que quelqu'un qui cherche la même réponse ne se soit pas rendu compte que vous pourriez être en mesure d'obtenir le nom d'utilisateur à travers le contexte de sécurité, et ne pas avoir à l'envoyer par l'url ou le corps à tout, ce qui me rend nerveux.

7
répondu orbfish 2014-01-06 20:24:10

je pense que meilleure idée serait:

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)

concernant la fourniture des données:

  • pour réinitialiser le mot de passe actuel

    • email doit être donné dans le corps.
  • pour créer un nouveau mot de passe (après réinitialisation)

    • nouveau mot de passe, code d'activation et emailID doit être administré dans le corps.
  • pour mettre à jour le mot de passe (pour l'utilisateur loggedIn)

    • ancien mot de passe, nouveau mot de passe doit être mentionné dans le corps.
    • UserId in Params.
    • Auth Token dans les en-têtes.
5
répondu codesnooker 2017-11-24 14:25:58

Je n'aurais pas quelque chose qui change le mot de passe et leur en envoie un nouveau si vous décidez d'utiliser la méthode /users/{id}/password, et de vous en tenir à votre idée que la demande est une ressource propre. ie /utilisateur-mot de passe-demande/ est la ressource, et permet de METTRE, les infos de l'utilisateur doit être dans le corps. Je ne changerais pas le mot de passe cependant, Id envoyer un email à l'utilisateur qui contient un lien vers une page qui contient un request_guid, qui pourrait être transmis avec une demande de poster /utilisateurs/{id}//mot de passe?request_guid=xxxxx

qui changerait le mot de passe, et il ne permet pas à quelqu'un d'arroser un utilisateur en demandant un changement de mot de passe.

Plus le PUT initial pourrait échouer s'il y a une demande en suspens.

2
répondu bpeikes 2014-09-03 02:51:50

il y a quelques considérations à prendre:

les réinitialisations de mot de passe ne sont pas idempotent

un changement de mot de passe affecte les données utilisées comme justificatifs d'identité pour l'effectuer, ce qui en conséquence pourrait invalider les tentatives futures si la demande est simplement répétée mot à mot tandis que les justificatifs d'identité stockés ont changé. Par exemple, si un token de réinitialisation temporaire est utilisé pour permettre le changement, comme il est d'usage dans une situation de mot de passe oublié, ce token devrait être expirée lors d'un changement de mot de passe réussi, ce qui annule encore une fois d'autres tentatives de répliquer la demande. Ainsi, une approche reposante à un changement de mot de passe semble être un travail mieux adapté pour POST que PUT .

Url avec ID d'espaces réservés sont pas de Repos

une ressource qui est spécifiée comme /password-reset/{user_id} implique que l'url réelle pointant vers la ressource doit être construite avec l'information hors bande (c'est-à-dire que nous avons besoin d'avoir précédent connaissance de user_id ), non acquise par la découverte. Il suppose en outre que nous aurons accès à cette information au moment de la demande, ce qui, dans de nombreuses situations, ne sera pas le cas.

ID ou e-mail dans la charge de données est probablement redondant

bien que ce ne soit pas contre le repos et peut avoir un but spécial, il est souvent inutile de spécifier un ID ou une adresse e-mail pour une réinitialisation de mot de passe. Pensez-y, pourquoi vous fournir l'adresse de courriel que une partie des données à une demande qui est censé passer par l'authentification d'une manière ou d'une autre? Si l'utilisateur change simplement son mot de passe, il doit s'authentifier pour le faire (via nom d'utilisateur:mot de passe, email:Mot de passe, ou token d'accès fourni via des en-têtes). Nous avons donc accès à leur compte à partir de cette étape. S'ils avaient oublié leur mot de passe, ils auraient reçu un token de réinitialisation temporaire (par courriel) qu'ils peuvent utiliser spécifiquement comme justificatifs d'identité pour effectuer le changement. Et dans ce cas, l'authentification par jeton doit être suffisante pour identifier leur compte.

en tenant compte de tout ce qui précède voici ce que je crois être le schéma approprié pour un changement de mot de passe reposant:

L'utilisateur connaît son mot de passe:

Method: POST
url: /v1/account/password
Auth (via headers): joe@example.com:my 0ld pa55wOrd
data load: {"password": "This 1s My very New Passw0rd"}

L'utilisateur ne connaît pas son mot de passe (réinitialisation du mot de passe par courriel):

Method: POST
url: /v1/account/password
Access Token (via headers): pwd_rst_token_b3xSw4hR8nKWE1d4iE2s7JawT8bCMsT1EvUQ94aI
data load: {"password": "This 1s My very New Passw0rd"}
2
répondu Michael Ekoka 2018-06-23 13:33:27

nous mettons à jour le mot de passe de l'utilisateur PUT/v1/users / password - identifiez L'identifiant de l'utilisateur en utilisant Accestoken.

il n'est pas sûr d'échanger le nom d'utilisateur. L'API Restful doit identifier L'utilisateur en utilisant Accessstoken reçu dans L'en-tête HTTP.

exemple dans la botte à ressort

@putMapping(value="/v1/users/password")
public ResponseEntity<String> updatePassword(@RequestHeader(value="Authorization") String token){
/* find User Using token */
/* Update Password*?
/* Return 200 */
}
0
répondu Dan 2018-02-28 15:38:33