作為 SQL 新手,我正在撰寫一個 API 中間件作為練習,用于檢查某些標頭中包含的資訊是否與資料庫條目匹配(“基于令牌的身份驗證”)。資料庫訪問基于GORM.
為此,我將我的 ORM 定義如下:
type User struct {
ID uint
UserName string
Token string
}
在我的中間件中,我檢索相關標頭的內容并以變數userHeader和tokenHeader. 它們應該與資料庫匹配以進行身份??驗證。
該user表只有一個條目:
select * from users
// 1,admin,admintoken
驗證碼是
var auth User
res := db.Where(&User{UserName: userHeader, Token: tokenHeader}).Find(&auth)
if res.RowsAffected == 1 {
// authentication succeeded
}
對此進行測驗時,我得到以下兩個不正確的結果(其他組合是正確的):
- 只有一個標頭設定為正確的值(另一個不存在),身份驗證成功(添加具有不正確值的另一個標頭是可以的(=auth 失敗))
- 沒有設定標題→身份驗證通過
我希望我的查詢意味著(在上述不正確結果的情況下)
select * from users where users.user_name = 'admin' and users.token = ''
select * from users where users.user_name = '' and users.token = ''
并且此查詢在控制臺上是正確的,即產生零結果(針對資料庫運行)。
然而,ORM 似乎丟棄了不存在的標題并假設它們很好(這至少是我的理解)
我還嘗試通過鏈接Where子句
db.Where(&User{UserName: userHeader}).Where(&User{Token: tokenHeader}).Find(&auth)
但結果是一樣的。
正確的查詢應該是什么?
uj5u.com熱心網友回復:
gorm.io檔案對在條件句中使用結構進行了以下說明Where:
使用 struct 查詢時,GORM只會查詢非零欄位,這意味著如果您的欄位的值為
0,或其他零值'',false則不會用于構建查詢條件...
建議的解決方案是:
要在查詢條件中包含零值,您可以使用映射,它將包含所有鍵值作為查詢條件...
因此,當令牌標頭或兩個標頭都為空時,但您仍希望將它們包含在WHERE生成的查詢的子句中,您需要使用 amap而不是 struct 作為Where方法的引數。
db.Where(map[string]interface{}{"user_name": userHeader, "token": tokenHeader}).Find(&auth)
您可以使用Debug()檢查生成的 SQL(它被列印到 stderr);如果您不確定您的代碼生成什么 SQL,請使用它
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/429835.html
