英文:
hashedSecret too short to be a bcrypted password not auth
问题
我正在从这篇博客文章中适应登录功能。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
}
我在PostgreSQL中创建了一个表,如下所示:
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
英文:
I'm adapting the login function from this blogpost. The User struct (see below) has four fields, id, name, email and password. You can see a row from the database below. The fmt.Println
in the login function shows the user to be like this after the query to the database
&{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]}
In other words, it has the id
(3), the name
(testuser), the hashed password, but then also an array of numbers which surprised me a bit because it's not in the row from the database (see below). You'll also notice that the fmt.Println
is not displaying the email, even though that's visible in the row from the database, so there seems to be a problem here.
When bcrypt compares the hash and the password in the Login
function, it's giving me this error
hashedSecret too short to be a bcrypted password not auth
Can you explain why this error's being thrown?
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
}
I have a user struct with the following fields
type User struct {
Id int
Name string
Email string
Password []byte
}
I created a table for it in postgres like this
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);
this is a row from the database
id | username | email | password
----+------------+----------------------+----------------------------------------------------------------------------------------------------------------------------
3 | testuser | testuser@gmail.com | \x24326124313024685337737468386a49424e322f495846545742696275334b6f3542586d397a484f35414a5a524162414f51303475762e477335596d
答案1
得分: 6
数字数组是电子邮件地址。
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
设置为 email
,Email
设置为 password
。换句话说,u.Password
包含了 email
(它们具有相同的 Go 数据类型),而 email
太短无法伪装成哈希密码。
在 select
和 Scan
中匹配字段,例如:
"select id, username, password, email from users where email=$1 "
Scan(&u.Id, &u.Name, &u.Password, &u.Email)
英文:
The array of numbers is the email address.
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))
}
Output:
[116 101 115 116 117 115 101 114 64 103 109 97 105 108 46 99 111 109]
testuser@gmail.com
After further study, I see you have select *
. Don't do that! You get items returned by the database, not necessarily what you want. Always be explicit in the fields you want returned and their order.
From the select *
, using the CREATE TABLE
definition, you likely got id
, username
, email
, and password
. From your Scan
, you set User
type Id
to id
, Name
to username
, Password
to email
, and Email
to password
. In other words, u.Password
contains email
(they have the same Go data type) and email
is too short to masquerade as a hashed password.
Match the fields in the select
and the Scan
, for example,
"select id, username, password, email from users where email=$1 "
Scan(&u.Id, &u.Name, &u.Password, &u.Email)
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论