轉向下一個 API。
PUT 於 /api/reset-password, req -> OTP、電子郵件、新密碼、資源 ->沒有內容
// controllers/passwordReset.go 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", }) } // no input field should be empty if input.OTP == "" || input.Email == "" || input.NewPassword == "" { return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{ "error": "invalid data", }) } // TODO: check redis for otp and update password return c.SendStatus(fiber.StatusNoContent) }
為其新增路線
// routes/routes.go api.Put("/reset-password", controllers.ResetPassword)
現在我需要兩個函數:
// utils/passwordReset.go func VerifyOTP(otp string, email string, c context.Context) (error, bool) { key := otpKeyPrefix + email // get the value for the key value, err := config.RedisClient.Get(c, key).Result() if err != nil { // the following states that the key was not found if err == redis.Nil { return errors.New("otp expired / incorrect email"), false } // for other errors return err, true } // compare received otp's hash with value in redis err = bcrypt.CompareHashAndPassword([]byte(value), []byte(otp)) if err != nil { return errors.New("incorrect otp"), false } // delete redis key to prevent abuse of otp 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") // hash the password hashedPassword, _ := bcrypt.GenerateFromPassword([]byte(password), 10) // update the password update := bson.M{ "$set": bson.M{ "password": hashedPassword, }, } _, err := users.UpdateByID(c, email, update) if err != nil { return err } return nil }
現在我需要將它們放在控制器中。我使用VerifyOTP函數中的bool來表示錯誤是內部錯誤還是由於輸入引起的。
// controllers/passwordReset.go 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", }) } // no input field should be empty if input.OTP == "" || input.Email == "" || input.NewPassword == "" { return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{ "error": "invalid data", }) } // check redis for otp 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) }
API現已建置完成,可以使用以下cURL指令進行測試
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" }'
在下一部分中,我將從前端開始
以上是密碼重設功能:使用 OTP 重設密碼的詳細內容。更多資訊請關注PHP中文網其他相關文章!