用户模型建立和注册
在接下来的内容中,我们将把重点转向用户:用户注册,激活,验证,以及根据用户拥有的权限限制对API接口的访问。
但在我们实现这些功能之前,需要为此打点基础。具体来说,我们需要:
- 在PostgreSQL中创建users表来存储用户信息
- 创建UserModel来对数据库中users进行操作,验证用户数据以及对用户密码进行hash处理。
- 开发POST /v1/users接口来实现用户注册。
创建Users数据库表
首先在数据库中创建一张新的users表。如果你跟随本系列文章操作,使用迁移工具生成一对新的SQL迁移文件:
$ migrate create -seq -ext=.sql -dir=./migrations create_users_table
/home/alex/Projects/greenlight/migrations/000004_create_users_table.up.sql
/home/alex/Projects/greenlight/migrations/000004_create_users_table.down.sql
然后将下面的SQL语句分别添加到up和down文件中:
File: migreates/000004_create_users_table.up.sql
CREATE TABLE IF NOT EXISTS users (
id bigserial PRIMARY KEY,
create_at timestamp(0) with time zone NOT NULL DEFAULT NOW(),
name text NOT NULL,
email citext UNIQUE NOT NULL,
password_hash bytea NOT NULL,
activated bool NOT NULL,
version integer NOT NULL DEFAULT 1
);
File: migrations/000004_create_users_table.down.sql
DROP TABLE IF EXISTS users;
关于CREATE TABLE语句有一些有趣的地方,我想快速解释一下:
1、email类型为citext(不区分大小写)。这类文本信息按原样存储,和区分大小写类型的数据相比,对其不做任何修改,包括对相关索引的查找。
2、在email列还加了UNIQUE约束。结合citext类型,这意味着表中不存在多行具备一样的email值,即使其他大小写不同。这实质上做了一个数据库级业务规则,即不应该有两个用户具有相同的电子邮件地址。
3、password_hash类型为bytea(二进制字符串)。在这列,我们将存储使用bcrypt生成的用户密码的散列值——而不是明文密码。
4、activated存储布尔类型值表示用户账号是否激活。创建用户时默认是false,要求用户确认email地址才能设置为true。
5、这里我们也包含version列,每次数据的更新都自增1。这将允许我们在更新用户记录时使用乐观锁定来防止竞争条件,就像我们在前面对movie表所做的那样。
好了,下面执行数据库“up”迁移:
$ migrate -path=./migrations -database=$GREENLIGHT_DB_DSN up
4/u create_users_table (139.162166ms)
然后,连接到你的数据库,并验证新的用户表已经创建,如预期:
psql $GREENLIGHT_DB_DSN
psql (13.4)
Type "help" for help.
greenlight=> \d users
Table "public.users"
Column | Type | Collation | Nullable | Default
---------------+-----------------------------+-----------+----------+------------------------
id | bigint | | not null | nextval('users_id_seq'::regclass)
create_at | timestamp(0) with time zone | | not null | now()
name | text | | not null |
email | citext | | not null |
password_hash | bytea | | not null |
activated | boolean | | not null |
version | integer | | not null | 1
Indexes:
"users_pkey" PRIMARY KEY, btree (id)
"users_email_key" UNIQUE CONSTRAINT, btree (email)
这里需要指出的一件重要的事情是:电子邮件列上的UNIQUE约束已经自动分配了名称users_email_key。这和下一节要介绍的内容相关,当处理用户使用相同的邮件地址注册两次所引起的任何错误时有用。
网友评论