我正在调整this blogpost的登录功能。 User结构(见下文)有四个字段,id,name,email和password。您可以在下面的数据库中看到一行。登录功能中的fmt.Println
在查询数据库后显示用户是这样的
&{3 testuser $2a$10$hS7sth8jIBN2/IXFTWBibu3Ko5BXm9zHO5AJZRAbAOQ04uv.Gs5Ym [116 101 115 116 117 115 101 114 64 103 109 97 105 108 46 99 111 109]}
换句话说,它有id
(3),name
(testuser),哈希密码,但也有一些数字让我感到惊讶,因为它'不在数据库的行中(见下文)。您还会注意到fmt.Println
没有显示电子邮件,即使数据库中的行可见,因此这里似乎存在问题。
当bcrypt比较Login
函数中的哈希值和密码时,它会给我这个错误
hashedSecret too short to be a bcrypted password not auth
你能解释为什么这个错误会被抛出吗?
func Login(password, email string) (u *User, err error) {
u = &User{}
err = db.QueryRow("select * from users where email=$1 ", email).Scan(&u.Id, &u.Name, &u.Password, &u.Email)
fmt.Println("u", u)
if err != nil {
fmt.Println("err", err)
}
err = bcrypt.CompareHashAndPassword(u.Password, []byte(password))
if err != nil {
u = nil
}
return
}
我有一个包含以下字段的用户结构
type User struct {
Id int
Name string
Email string
Password []byte
}
我在这样的postgres中为它创建了一个表
CREATE TABLE "public"."users" (
"id" int4 NOT NULL DEFAULT nextval('users_id_seq'::regclass),
"username" varchar(255) NOT NULL COLLATE "default",
"email" varchar(255) NOT NULL COLLATE "default",
"password" bytea
)
WITH (OIDS=FALSE);
这是数据库中的一行
id | username | email | password
----+------------+----------------------+----------------------------------------------------------------------------------------------------------------------------
3 | testuser | testuser@gmail.com | \x24326124313024685337737468386a49424e322f495846545742696275334b6f3542586d397a484f35414a5a524162414f51303475762e477335596d
答案 0 :(得分:3)
数字数组是电子邮件地址。
package main
import (
"fmt"
)
func main() {
email := []byte{116, 101, 115, 116, 117, 115, 101, 114, 64, 103, 109, 97, 105, 108, 46, 99, 111, 109}
fmt.Println(email)
fmt.Println(string(email))
}
输出:
[116 101 115 116 117 115 101 114 64 103 109 97 105 108 46 99 111 109]
testuser@gmail.com
经过进一步研究,我发现你有select *
。别这么做!您将获得数据库返回的项目,而不一定是您想要的项目。始终在要返回的字段及其顺序中明确。
使用select *
定义从CREATE TABLE
开始,您可能会获得id
,username
,email
和password
。在Scan
,您设置User
类型Id
至id
,Name
至username
,Password
至{{1} }和email
到Email
。换句话说,password
包含u.Password
(它们具有相同的Go数据类型),而email
太短,无法伪装成哈希密码。
匹配email
和select
中的字段,例如
Scan