猿问

PlaceHolderFormat 不会在 SQL 期间使用 pgx 驱动程序替换参数值的美元符号

我是Go的新手,并且正在尝试根据postgresql数据库中的用户名检查密码。


我无法让美元替换发生,宁愿不诉诸于连接字符串。


我目前正在使用松鼠,但也尝试过,没有,没有太多的运气。


我有以下代码:


    package datalayer


import (

    "database/sql"

    "encoding/json"

    "fmt"

    "net/http"


    sq "github.com/Masterminds/squirrel"

    _ "github.com/jackc/pgx/v4/stdlib"

    "golang.org/x/crypto/bcrypt"


    "github.com/gin-gonic/gin"

)


var (

    // for the database

    db *sql.DB

)


func InitDB(sqlDriver string, dataSource string) error {

    var err error


    // Connect to the postgres db  (sqlDriver is literal string "pgx")

    db, err = sql.Open(sqlDriver, dataSource)


    if err != nil {

        panic(err)

    }

    return db.Ping()

}


// Create a struct that models the structure of a user, both in the request body, and in the DB

type Credentials struct {

    Password string `json:"password", db:"password"`

    Username string `json:"username", db:"username"`

}


func Signin(c *gin.Context) {

    // Parse and decode the request body into a new `Credentials` instance

    creds := &Credentials{}

    err := json.NewDecoder(c.Request.Body).Decode(creds)



    if err != nil {

        // If there is something wrong with the request body, return a 400 status

        c.Writer.WriteHeader(http.StatusBadRequest)

        return

    }

    query := sq.

        Select("password").

        From("users").

        Where("username = $1", creds.Username).

        PlaceholderFormat(sq.Dollar)


        // The line below doesn't substitute the $ sign, it shows this:  SELECT password FROM users WHERE username = $1 [rgfdgfd] <nil>

    fmt.Println(sq.

        Select("password").

        From("users").

        Where("username = $1", creds.Username).

        PlaceholderFormat(sq.Dollar).ToSql())


    rows, sqlerr := query.RunWith(db).Query()

    if sqlerr != nil {

        panic(fmt.Sprintf("QueryRow failed: %v", sqlerr))

    }


    if err != nil {

        // If there is an issue with the database, return a 500 error

        c.Writer.WriteHeader(http.StatusInternalServerError)

        return

    }

  

当我检查pgAdmin时,我看到以下内容,显示美元符号未被替换:

森林海
浏览 143回答 1
1回答

慕尼黑5688855

占位符的替换是由postgres服务器完成的,不应该是Go代码或松鼠的工作来做替换。在执行采用参数的查询时,数据库驱动程序必须执行的操作的大致概述如下所示:使用查询字符串(占位符保持不变),将向 postgres 服务器发送请求以创建预准备语句。parse使用参数值和新创建的语句的标识符,发送一个请求,通过创建门户使语句准备好执行。门户(类似于游标,但不相同)表示准备执行或已部分执行的语句,并填充任何缺少的参数值。bind使用门户的标识符将请求发送到服务器,然后服务器执行门户的查询。execute请注意,上述步骤只是一个粗略的概述,实际上数据库客户端和服务器之间涉及更多的请求 - 响应周期。就目前而言,我相信它向您显示的是请求创建的准备好的声明,尽管由于我不熟悉它,因此我无法确定。pgAdminparse从理论上讲,像 这样的帮助程序库或类似的驱动程序库可以实现参数本身的替换,然后向服务器发送一个简单的查询。但是,一般来说,考虑到SQL注入的可能性,在我看来,最好将其留给postgres服务器的权威。squirrelpgx的工作是简单地将占位符转换为指定的格式。例如,您可以使用MySQL格式编写SQL,然后调用该方法将其转换为PostgreSQL格式。PlaceholderFormat(?,?,...)PlaceholderFormat(sql.Dollar)($1,$2,...)
随时随地看视频慕课网APP

相关分类

Go
我要回答