SQLite3与Rack Basic Auth:用户名无法作为执行参数问题
解决方案
直接修复代码
将Rack传入的username转换为UTF-8编码并清理空白字符,替换原查询代码:
p db.execute("select * from user where name = ?", [username.encode('UTF-8', invalid: :replace, undef: :replace).strip])
问题根源
Rack的Basic Auth组件解析出的用户名默认是ASCII-8BIT(二进制)编码的字符串,而你数据库中name字段存储的是UTF-8编码内容。尽管两者字符内容、长度完全一致,但编码标识不匹配,SQLite会判定为不同字符串,导致查询无结果。
之前使用to_s无效是因为该方法不会改变字符串编码,仅返回自身;手动赋值的字符串是Ruby默认的UTF-8编码,因此能正常匹配。
验证编码差异
可以在代码中添加编码打印来确认:
p username.encoding # 输出: #<Encoding:ASCII-8BIT> p "my_user_name".encoding # 输出: #<Encoding:UTF-8>
额外优化建议
为避免后续编码兼容问题,建议在用户数据存储和查询环节统一使用UTF-8编码,覆盖所有输入场景的编码转换。
内容的提问来源于stack exchange,提问作者Jomy
相关产品推荐
相关产品推荐

