You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用Go-Fiber和MongoDB配置Go登录认证及修复登录接口panic问题

错误根源分析

  • 全局*mongo.Client变量未初始化。注册功能走的是dao.UserData封装的数据库操作,没有直接使用全局client,而登录函数直接调用client.Database,如果client为nil就会直接触发空指针panic,这是你看到SIGSEGV错误的核心原因。
  • 登录逻辑变量赋值错误。你声明了var user models.User但没有将请求解析到的data赋值给它,查询数据库用的user.Email是空值,后续密码比对用的user.Password也是零值,完全无法完成校验。
  • 请求字段名不匹配。注册时取的密码字段是data["password"],登录时写成了data["passwd"],永远拿不到正确的用户输入密码。
  • 错误处理缺失。FindOne查询出错后仅打印状态码,没有终止流程,后续逻辑会继续执行空值操作,也会触发panic。

解决方案

第一步:初始化全局Mongo客户端

确保程序启动阶段就完成Mongo连接初始化,给全局client变量赋值,示例初始化代码参考:

// 程序启动时调用该方法初始化Mongo连接
func InitMongo() error {
    ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
    defer cancel()
    var err error
    client, err = mongo.Connect(ctx, options.Client().ApplyURI("你的Mongo连接串"))
    if err != nil {
        return err
    }
    // 测试连接可用性
    return client.Ping(ctx, readpref.Primary())
}

如果你已经有dao层封装的数据库操作,建议登录也复用dao层的查询方法,避免直接操作全局client,减少空指针风险。

第二步:重写Login函数修正逻辑

修正后的完整登录函数如下:

func Login(c *fiber.Ctx) error {
    // 1. 解析请求参数
    var data map[string]string
    if err := c.BodyParser(&data); err != nil {
        return err
    }
    // 校验必填参数
    if data["email"] == "" || data["password"] == "" {
        c.Status(fiber.StatusBadRequest)
        return c.JSON(fiber.Map{
            "message": "邮箱和密码不能为空",
        })
    }

    // 2. 根据邮箱查询数据库用户
    // 这里优先推荐复用dao层的查询方法,如果要直接用client请先确保client已初始化
    collection := client.Database("Shashank").Collection("User")
    ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
    defer cancel() // 必须释放context资源
    
    var dbUser models.User
    err := collection.FindOne(ctx, bson.M{"email": data["email"]}).Decode(&dbUser)
    if err != nil {
        c.Status(fiber.StatusBadRequest)
        return c.JSON(fiber.Map{
            "message": "用户不存在",
        })
    }

    // 3. 比对密码
    err = bcrypt.CompareHashAndPassword(dbUser.Password, []byte(data["password"]))
    if err != nil {
        c.Status(fiber.StatusBadRequest)
        return c.JSON(fiber.Map{
            "message": "密码错误",
        })
    }

    // 4. 登录成功返回用户信息(实际生产建议返回JWT token而不是完整用户信息,尤其是不要返回密码)
    dbUser.Password = nil // 清空密码字段再返回
    return c.JSON(dbUser)
}

内容的提问来源于stack exchange,提问作者S H A S H A N K

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.01 03:39:03