我正在构建一个接受发布到它的JSON数据的API。
我有以下user
结构,最近我将password
数据类型从[]byte
更改为string
,以便它与bcrypt包“完美匹配”。
type User struct {
Id string `json:"id,omitempty"`
Email string `json:"email,omitempty"`
Username string `json:"username,omitempty"`
Password []byte `json:"password,omitempty"`
Name string `json:"name,omitempty"`
}
但是,当用户使用5个或更多字符的密码进行POST时,我现在收到JSON响应输入字节4中的非法base64数据中返回的内部错误。如果密码为4个或更少字符,则没有问题。
我已经将错误指向了这段代码:
err := json.NewDecoder(req.Body).Decode(User)
if err != nil && err != io.EOF {
return err
}
关于修复的任何想法?
答案 0 :(得分:9)
问题在于使用[]byte
代替string
来获取密码。这是因为encoding/json
包在解码为[]byte
时需要base64编码的字符串。
encoding/json
的文档说:
数组和切片值编码为JSON数组,除了[]字节编码为base64编码的字符串,而nil切片编码为空JSON对象。
所以,只需将其更改为string
:
Password string `json:"password,omitempty"`
如果您想将其与bcrypt一起使用,那么您只需将string
转换为[]byte
:
[]byte(user.Password)
答案 1 :(得分:0)
如果要直接从JSON中提取字节数组,可以使用*json.RawMessage
(在Go 1.9中)定义的数据类型encoding/json/stream.go:247
:
type RawMessage []byte
这种特殊类型指示unmarshaller跳过解码并简单地创建相关字节的片段。由于这仍然只是一个字节数组,您可以直接使用它与bcrypt函数:
type User struct {
...
Password *json.RawMessage `json:"password,omitempty"`
...
}
...
err := bcrypt.CompareHashAndPassword(*user.Password, storedPassword)
注意读取值时指针取消引用(*
)。