
Back-end
2. Réinitialisation du mot de passe
Passons à l'API suivante.
METTRE sur /api/reset-password, req -> otp, email, nouveau mot de passe, res -> pas de contenu
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | func ResetPassword(c *fiber.Ctx) error {
type Input struct {
OTP string `json: "otp" `
Email string `json: "email" `
NewPassword string `json: "new_password" `
}
var input Input
err := c.BodyParser(&input)
if err != nil {
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{
"error" : "invalid data" ,
})
}
if input.OTP == "" || input.Email == "" || input.NewPassword == "" {
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{
"error" : "invalid data" ,
})
}
return c.SendStatus(fiber.StatusNoContent)
}
|
Copier après la connexion
Ajout d'un itinéraire pour cela
1 2 | api.Put( "/reset-password" , controllers.ResetPassword)
|
Copier après la connexion
Maintenant, j'ai besoin de deux fonctions :
-
VérifierOTP -> entrée = OTP, e-mail ; sortie = erreur (le cas échéant)
-
Mettre à jour le mot de passe -> entrée = email, mot de passe ; sortie = erreur (le cas échéant)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 | func VerifyOTP(otp string, email string, c context.Context) (error, bool) {
key := otpKeyPrefix + email
value, err := config.RedisClient.Get(c, key).Result()
if err != nil {
if err == redis.Nil {
return errors.New( "otp expired / incorrect email" ), false
}
return err, true
}
err = bcrypt.CompareHashAndPassword([]byte(value), []byte(otp))
if err != nil {
return errors.New( "incorrect otp" ), false
}
err = config.RedisClient.Del(c, key).Err()
if err != nil {
return err, true
}
return nil, false
}
func UpdatePassword(email string, password string, c context.Context) error {
users := config.DB.Collection( "users" )
hashedPassword, _ := bcrypt.GenerateFromPassword([]byte(password), 10)
update := bson.M{
"$set" : bson.M{
"password" : hashedPassword,
},
}
_, err := users.UpdateByID(c, email, update)
if err != nil {
return err
}
return nil
}
|
Copier après la connexion
Maintenant, je dois les assembler tous les deux dans le contrôleur. J'utilise le booléen de la fonction VerifyOTP pour indiquer si l'erreur est une erreur interne ou si elle est due à l'entrée.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 | func ResetPassword(c *fiber.Ctx) error {
type Input struct {
OTP string `json: "otp" `
Email string `json: "email" `
NewPassword string `json: "new_password" `
}
var input Input
err := c.BodyParser(&input)
if err != nil {
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{
"error" : "invalid data" ,
})
}
if input.OTP == "" || input.Email == "" || input.NewPassword == "" {
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{
"error" : "invalid data" ,
})
}
err, isInternalErr := utils.VerifyOTP(input.OTP, input.Email, c.Context())
if err != nil {
var code int
if isInternalErr {
code = fiber.StatusInternalServerError
} else {
code = fiber.StatusUnauthorized
}
return c.Status(code).JSON(fiber.Map{
"error" : err.Error(),
})
}
err = utils.UpdatePassword(input.Email, input.NewPassword, c.Context())
if err != nil {
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{
"error" : err.Error(),
})
}
return c.SendStatus(fiber.StatusNoContent)
}
|
Copier après la connexion
L'API est maintenant construite et les tests peuvent être effectués à l'aide de la commande cURL suivante
1 2 3 4 5 6 7 | curl --location --request PUT 'localhost:3000/api/reset-password' \
--header 'Content-Type: application/json' \
--data-raw '{
"email" : "yashjaiswal.cse@gmail.com" ,
"new_password" : "tester123" ,
"otp" : "DM4RDNF07B"
}'
|
Copier après la connexion
Dans la prochaine partie, je commencerai par le frontend
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!