package main import ( "database/sql" "fmt" "log" "net/http" "os" "github.com/gin-gonic/gin" _ "github.com/lib/pq" "golang.org/x/crypto/bcrypt" ) // UpdatePasswordRequest 更新密码请求参数结构 type UpdatePasswordRequest struct { UserID string `json:"user_id" binding:"required"` OldPassword string `json:"old_password" binding:"required"` NewPassword string `json:"new_password" binding:"required,min=6"` } // UpdatePasswordResponse 更新密码响应结构 type UpdatePasswordResponse struct { Success bool `json:"success"` Message string `json:"message"` } var db *sql.DB func main() { // 初始化日志输出格式 log.SetFlags(log.Ldate | log.Ltime | log.Lshortfile) log.Println("开始初始化应用程序") // 初始化Gin引擎 r := gin.Default() log.Println("Gin引擎初始化完成") // 从环境变量获取数据库配置 dbHost := os.Getenv("DB_HOST") dbPort := os.Getenv("DB_PORT") dbUser := os.Getenv("DB_USER") dbPassword := os.Getenv("DB_PASSWORD") dbName := os.Getenv("DB_NAME") log.Printf("读取数据库配置: host=%s, port=%s, user=%s, dbname=%s", dbHost, dbPort, dbUser, dbName) // 构建数据库连接字符串 connStr := fmt.Sprintf( "host=%s port=%s user=%s password=%s dbname=%s sslmode=disable", dbHost, dbPort, dbUser, dbPassword, dbName, ) var err error db, err = sql.Open("postgres", connStr) if err != nil { log.Panicf("无法连接数据库: %v", err) } defer db.Close() log.Println("数据库连接对象创建成功") // 验证数据库连接 if err := db.Ping(); err != nil { log.Panicf("数据库连接失败: %v", err) } log.Println("数据库连接验证成功") // 更新密码接口 r.POST("/user/update/password", updatePasswordHandler) log.Println("注册更新密码接口: POST /user/update/password") // 启动服务,监听80端口 log.Println("服务启动在80端口") if err := r.Run(":80"); err != nil { log.Panicf("服务启动失败: %v", err) } } // updatePasswordHandler 处理密码更新逻辑 func updatePasswordHandler(c *gin.Context) { requestID := c.Request.Header.Get("X-Request-ID") if requestID == "" { requestID = fmt.Sprintf("req-%d", gin.Mode()) } log.Printf("[%s] 收到更新密码请求 from %s", requestID, c.ClientIP()) var req UpdatePasswordRequest // 绑定并验证请求参数 if err := c.ShouldBindJSON(&req); err != nil { log.Printf("[%s] 请求参数绑定失败: %v", requestID, err) c.JSON(http.StatusBadRequest, UpdatePasswordResponse{ Success: false, Message: "请求参数错误: " + err.Error(), }) return } log.Printf("[%s] 请求参数验证通过, 用户ID: %s", requestID, req.UserID) // 1. 检查新旧密码是否一致 if req.OldPassword == req.NewPassword { log.Printf("[%s] 新密码与旧密码相同, 用户ID: %s", requestID, req.UserID) c.JSON(http.StatusOK, UpdatePasswordResponse{ Success: false, Message: "新密码不能与旧密码相同", }) return } // 2. 对旧密码进行加密处理 log.Printf("[%s] 开始对旧密码进行加密, 用户ID: %s", requestID, req.UserID) hashedOldPassword, err := bcrypt.GenerateFromPassword([]byte(req.OldPassword), bcrypt.DefaultCost) if err != nil { log.Printf("[%s] 旧密码加密失败: %v, 用户ID: %s", requestID, err, req.UserID) c.JSON(http.StatusInternalServerError, UpdatePasswordResponse{ Success: false, Message: "旧密码加密失败: " + err.Error(), }) return } log.Printf("[%s] 旧密码加密完成, 用户ID: %s", requestID, req.UserID) // 3. 使用加密后的旧密码查询并验证(按user_id匹配) var count int query := ` SELECT COUNT(*) FROM user_password WHERE user_id = $1 AND password = $2 ` log.Printf("[%s] 执行旧密码验证查询, SQL: %s, 参数: [%s, ****]", requestID, query, req.UserID) err = db.QueryRow(query, req.UserID, string(hashedOldPassword)).Scan(&count) if err != nil { log.Printf("[%s] 旧密码验证查询失败: %v, 用户ID: %s", requestID, err, req.UserID) c.JSON(http.StatusInternalServerError, UpdatePasswordResponse{ Success: false, Message: "验证旧密码失败: " + err.Error(), }) return } // 验证失败处理 if count == 0 { log.Printf("[%s] 旧密码验证失败, 用户ID: %s", requestID, req.UserID) c.JSON(http.StatusOK, UpdatePasswordResponse{ Success: false, Message: "旧密码不正确", }) return } log.Printf("[%s] 旧密码验证成功, 用户ID: %s", requestID, req.UserID) // 4. 对新密码进行加密处理 log.Printf("[%s] 开始对新密码进行加密, 用户ID: %s", requestID, req.UserID) hashedNewPassword, err := bcrypt.GenerateFromPassword([]byte(req.NewPassword), bcrypt.DefaultCost) if err != nil { log.Printf("[%s] 新密码加密失败: %v, 用户ID: %s", requestID, err, req.UserID) c.JSON(http.StatusInternalServerError, UpdatePasswordResponse{ Success: false, Message: "新密码加密失败: " + err.Error(), }) return } log.Printf("[%s] 新密码加密完成, 用户ID: %s", requestID, req.UserID) // 5. 更新密码表中的密码(按user_id匹配) updateQuery := ` UPDATE user_password SET password = $1 WHERE user_id = $2 ` log.Printf("[%s] 执行密码更新, SQL: %s, 参数: [****, %s]", requestID, updateQuery, req.UserID) result, err := db.Exec(updateQuery, string(hashedNewPassword), req.UserID) if err != nil { log.Printf("[%s] 密码更新执行失败: %v, 用户ID: %s", requestID, err, req.UserID) c.JSON(http.StatusInternalServerError, UpdatePasswordResponse{ Success: false, Message: "更新密码失败: " + err.Error(), }) return } // 6. 检查更新结果 rowsAffected, err := result.RowsAffected() if err != nil { log.Printf("[%s] 获取更新行数失败: %v, 用户ID: %s", requestID, err, req.UserID) c.JSON(http.StatusInternalServerError, UpdatePasswordResponse{ Success: false, Message: "检查更新结果失败: " + err.Error(), }) return } log.Printf("[%s] 密码更新影响行数: %d, 用户ID: %s", requestID, rowsAffected, req.UserID) if rowsAffected == 0 { log.Printf("[%s] 未找到用户或密码未变化, 用户ID: %s", requestID, req.UserID) c.JSON(http.StatusOK, UpdatePasswordResponse{ Success: false, Message: "未找到用户或密码未发生变化", }) return } // 7. 更新成功 log.Printf("[%s] 密码更新成功, 用户ID: %s", requestID, req.UserID) c.JSON(http.StatusOK, UpdatePasswordResponse{ Success: true, Message: "密码更新成功", }) }