作为 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) 但结果是一样的。正确的查询应该是什么?
1 回答
慕莱坞森
TA贡献1810条经验 获得超4个赞
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,请使用它
- 1 回答
- 0 关注
- 199 浏览
添加回答
举报
0/150
提交
取消