我是 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
}
// We create another instance of `Credentials` to store the credentials we get from the database
storedCreds := &Credentials{}
// Store the obtained password in `storedCreds`
err = rows.Scan(&storedCreds.Password)
if err != nil {
// If an entry with the username does not exist, send an "Unauthorized"(401) status
if err == sql.ErrNoRows {
c.Writer.WriteHeader(http.StatusUnauthorized)
return
}
// If the error is of any other type, send a 500 status
c.Writer.WriteHeader(http.StatusInternalServerError)
return
}
// Compare the stored hashed password, with the hashed version of the password that was received
if err = bcrypt.CompareHashAndPassword([]byte(storedCreds.Password), []byte(creds.Password)); err != nil {
// If the two passwords don't match, return a 401 status
c.Writer.WriteHeader(http.StatusUnauthorized)
}
fmt.Printf("We made it !")
// If we reach this point, that means the users password was correct, and that they are authorized
// The default 200 status is sent
}
当我检查 pgAdmin 时,我看到以下内容,这表明美元符号未被替换: