微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何在 go-gin 框架中验证 API 密钥?

如何解决如何在 go-gin 框架中验证 API 密钥?

所以我目前有一个函数可以接受一个字符串 APIKey 来根据我的 MongoDB 集合检查它。如果未找到任何内容(未通过身份验证),则返回 false - 如果找到用户,则返回 true。但是,我的问题是我不确定如何将其与 Gin POST 路由集成。这是我的代码


import (
    "context"
    "fmt"
    "log"
    "os"

    "github.com/gin-gonic/gin"
    _ "github.com/joho/godotenv/autoload"
    "go.mongodb.org/mongo-driver/bson"
    "go.mongodb.org/mongo-driver/bson/primitive"
    "go.mongodb.org/mongo-driver/mongo"
    "go.mongodb.org/mongo-driver/mongo/options"
)

type User struct {
    Name   string
    APIKey string
}

func validateAPIKey(users *mongo.Collection,APIKey string) bool {
    var user User

    filter := bson.D{primitive.E{Key: "APIKey",Value: APIKey}}
    if err := users.FindOne(context.Todo(),filter).Decode(&user); err != nil {
        fmt.Printf("Found 0 results for API Key: %s\n",APIKey)
        return false
    }

    fmt.Printf("Found: %s\n",user.Name)
    return true
}

func handleUpload(c *gin.Context) {

}

func main() {
    r := gin.Default()

    api := r.Group("/api")
    v1 := api.Group("/v1")

    v1.POST("/upload",handleUpload)

    mongoURI := os.Getenv("MONGO_URI")
    mongoOptions := options.Client().ApplyURI(mongoURI)
    client,err := mongo.Connect(context.Todo(),mongoOptions)
    if err != nil {
        log.Fatal(err,"Unable to access MongoDB server,exiting...")
    }
    defer client.disconnect(context.Todo())

    // users := client.Database("sharex_api").Collection("authorized_users") // commented out when testing to ignore unused warnings

    r.Run(":8085")
}

如果单独测试,validateAPIKey 函数完全按预期工作,我只是不确定如何为特定端点(在本例中为 /api/v1/upload)运行此函数并传入用户集合。

解决方法

经过一番搜索,我找到了一个解决方案。我将 validateAPIKey 函数更改为返回 git.HandlerFunc。代码如下:

func validateAPIKey(users *mongo.Collection) gin.HandlerFunc {
    return func(c *gin.Context) {
        var user authorizedUser
        APIKey := c.Request.Header.Get("X-API-Key")

        filter := bson.D{primitive.E{Key: "APIKey",Value: APIKey}}
        if err := users.FindOne(context.TODO(),filter).Decode(&user); err != nil {
            fmt.Printf("Found 0 results for API Key: %s\n",APIKey)
            c.JSON(http.StatusUnauthorized,gin.H{"status": 401,"message": "Authentication failed"})
            return
        }

        return
    }
}

对于路线,我有以下内容:

v1.POST("/upload",validateAPIKey(users),handleUpload)

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。