Golang中如何开始比较并输出有用的错误信息

Golang中如何开始比较并输出有用的错误信息 我已经成功实现了密码哈希功能,但似乎无法在注册和登录过程中验证用户的邮箱和密码。

如何在这些代码中实现HTTP JSON响应?需要输出有用的错误信息,例如:“用户已使用相同邮箱注册、两个密码字段不匹配、密码长度少于8个字符”。在登录时,需要提示用户邮箱或密码不匹配。

以下是相关代码:

userregistration.go

func User_Collection(user *model.User) (*mongo.InsertOneResult, error) {
	collection := clientInstance.Database(AUTH_DB).Collection(USER_COLLECTION)
	user.Password = getHash([]byte(user.Password))
	return collection.InsertOne(context.TODO(), user)

}

func getHash(password []byte) string {
	hash, err := bcrypt.GenerateFromPassword(password, bcrypt.MinCost)
	if err != nil {
		log.Println(err)
	}
	return string(hash)
}

login.go

func Find_User(user *model.User) (model.User, error) {
	filter := bson.M{"email": user.Email}
	result := model.User{}
	err := clientInstance.Database(AUTH_DB).Collection(USER_COLLECTION).FindOne(context.Background(), filter).Decode(&result)
	if err != nil {
		if errors.Is(err, mongo.ErrNoDocuments) {
			return model.User{}, nil
		}
		return model.User{}, fmt.Errorf("finding user:%w", err)
	}
	return result, nil
}

更多关于Golang中如何开始比较并输出有用的错误信息的实战教程也可以访问 https://www.itying.com/category-94-b0.html

1 回复

更多关于Golang中如何开始比较并输出有用的错误信息的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


在注册和登录过程中实现有用的错误信息比较和HTTP JSON响应,需要添加验证逻辑并返回结构化的错误响应。以下是修改后的代码示例:

userregistration.go 修改:

func RegisterUser(user *model.User) (map[string]interface{}, error) {
    // 验证邮箱是否已存在
    existingUser, _ := FindUserByEmail(user.Email)
    if existingUser.Email != "" {
        return map[string]interface{}{
            "success": false,
            "error":   "用户已使用相同邮箱注册",
        }, nil
    }

    // 验证密码长度
    if len(user.Password) < 8 {
        return map[string]interface{}{
            "success": false,
            "error":   "密码长度少于8个字符",
        }, nil
    }

    // 哈希密码
    user.Password = getHash([]byte(user.Password))
    
    collection := clientInstance.Database(AUTH_DB).Collection(USER_COLLECTION)
    result, err := collection.InsertOne(context.TODO(), user)
    
    if err != nil {
        return map[string]interface{}{
            "success": false,
            "error":   "注册失败: " + err.Error(),
        }, err
    }

    return map[string]interface{}{
        "success": true,
        "message": "注册成功",
        "user_id": result.InsertedID,
    }, nil
}

func FindUserByEmail(email string) (model.User, error) {
    filter := bson.M{"email": email}
    result := model.User{}
    err := clientInstance.Database(AUTH_DB).Collection(USER_COLLECTION).
        FindOne(context.Background(), filter).Decode(&result)
    
    if err != nil {
        if errors.Is(err, mongo.ErrNoDocuments) {
            return model.User{}, nil
        }
        return model.User{}, err
    }
    return result, nil
}

login.go 修改:

func LoginUser(email, password string) (map[string]interface{}, error) {
    // 查找用户
    user, err := FindUserByEmail(email)
    if err != nil {
        return map[string]interface{}{
            "success": false,
            "error":   "查找用户失败: " + err.Error(),
        }, err
    }

    // 检查用户是否存在
    if user.Email == "" {
        return map[string]interface{}{
            "success": false,
            "error":   "邮箱或密码不匹配",
        }, nil
    }

    // 验证密码
    err = bcrypt.CompareHashAndPassword([]byte(user.Password), []byte(password))
    if err != nil {
        return map[string]interface{}{
            "success": false,
            "error":   "邮箱或密码不匹配",
        }, nil
    }

    return map[string]interface{}{
        "success": true,
        "message": "登录成功",
        "user": map[string]interface{}{
            "id":    user.ID,
            "email": user.Email,
        },
    }, nil
}

HTTP处理函数示例

func RegisterHandler(w http.ResponseWriter, r *http.Request) {
    var user model.User
    if err := json.NewDecoder(r.Body).Decode(&user); err != nil {
        respondWithError(w, http.StatusBadRequest, "无效的请求数据")
        return
    }

    // 验证两个密码字段是否匹配(假设user有ConfirmPassword字段)
    if user.Password != user.ConfirmPassword {
        respondWithError(w, http.StatusBadRequest, "两个密码字段不匹配")
        return
    }

    response, err := RegisterUser(&user)
    if err != nil {
        respondWithError(w, http.StatusInternalServerError, "服务器内部错误")
        return
    }

    w.Header().Set("Content-Type", "application/json")
    json.NewEncoder(w).Encode(response)
}

func LoginHandler(w http.ResponseWriter, r *http.Request) {
    var credentials struct {
        Email    string `json:"email"`
        Password string `json:"password"`
    }

    if err := json.NewDecoder(r.Body).Decode(&credentials); err != nil {
        respondWithError(w, http.StatusBadRequest, "无效的请求数据")
        return
    }

    response, err := LoginUser(credentials.Email, credentials.Password)
    if err != nil {
        respondWithError(w, http.StatusInternalServerError, "服务器内部错误")
        return
    }

    w.Header().Set("Content-Type", "application/json")
    json.NewEncoder(w).Encode(response)
}

func respondWithError(w http.ResponseWriter, code int, message string) {
    w.Header().Set("Content-Type", "application/json")
    w.WriteHeader(code)
    json.NewEncoder(w).Encode(map[string]interface{}{
        "success": false,
        "error":   message,
    })
}

model.User结构体示例

type User struct {
    ID              primitive.ObjectID `bson:"_id,omitempty" json:"id,omitempty"`
    Email           string             `bson:"email" json:"email"`
    Password        string             `bson:"password" json:"password,omitempty"`
    ConfirmPassword string             `json:"confirmPassword,omitempty"` // 仅用于注册验证
}

这些修改实现了:

  1. 注册时的邮箱重复检查
  2. 密码长度验证
  3. 密码确认字段匹配验证
  4. 登录时的邮箱密码匹配验证
  5. 统一的JSON错误响应格式
  6. 具体的错误信息提示

所有错误信息都以结构化的JSON格式返回,前端可以轻松解析并显示给用户。

回到顶部