gorm 是否使用逻辑 OR 解释结构的内容?

作为 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) 

但结果是一样的。


正确的查询应该是什么?


料青山看我应如是
浏览 200回答 1
1回答

慕莱坞森

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,请使用它
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go