为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

Go
森林海 2022-09-05 10:39:34
我是Go的新手,并且正在尝试根据postgresql数据库中的用户名检查密码。我无法让美元替换发生,宁愿不诉诸于连接字符串。我目前正在使用松鼠,但也尝试过,没有,没有太多的运气。我有以下代码:    package datalayerimport (    "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 DBtype 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时,我看到以下内容,显示美元符号未被替换:
查看完整描述

1 回答

?
慕尼黑5688855

TA贡献1848条经验 获得超2个赞

占位符的替换是由postgres服务器完成的,不应该是Go代码或松鼠的工作来做替换。

在执行采用参数的查询时,数据库驱动程序必须执行的操作的大致概述如下所示:

  1. 使用查询字符串(占位符保持不变),将向 postgres 服务器发送请求以创建预准备语句parse

  2. 使用参数值和新创建的语句的标识符,发送一个请求,通过创建门户使语句准备好执行。门户(类似于游标,但不相同)表示准备执行或已部分执行的语句,并填充任何缺少的参数值。bind

  3. 使用门户的标识符将请求发送到服务器,然后服务器执行门户的查询。execute

请注意,上述步骤只是一个粗略的概述,实际上数据库客户端和服务器之间涉及更多的请求 - 响应周期。

就目前而言,我相信它向您显示的是请求创建的准备好的声明,尽管由于我不熟悉它,因此我无法确定。pgAdminparse


从理论上讲,像 这样的帮助程序库或类似的驱动程序库可以实现参数本身的替换,然后向服务器发送一个简单的查询。但是,一般来说,考虑到SQL注入的可能性,在我看来,最好将其留给postgres服务器的权威。squirrelpgx


的工作是简单地将占位符转换为指定的格式。例如,您可以使用MySQL格式编写SQL,然后调用该方法将其转换为PostgreSQL格式。PlaceholderFormat(?,?,...)PlaceholderFormat(sql.Dollar)($1,$2,...)


查看完整回答
反对 回复 2022-09-05
  • 1 回答
  • 0 关注
  • 142 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号