多种用户登录模式设计

在做Web开发的时候,用户登录时最基本的功能。通常情况下,我们直接使用“用户名+密码”的模式,直接在users表中建立用户名密码等字段来完成工作。但是,如果我们的要求是邮箱、手机号和接入第三方的登录都要支持呢?很明显,在这种情况下,基本的用户名密码登录是完成不了我们的要求的。

在这种情况下,我们可以采用“拆表”的方法。这里所谓的拆表就是将一个用户表拆分成为几个表:user_info,user_auth,user_extra等表。user_info表中保存用户的基本信息,如user_id,username,nickname等;user_auth表用来保存用户的认证信息,如user_id,identity_type,identifier和certificate等;user_extra表是用户信息的扩展表,用户的一些扩展信息可以保存在该表中。

表结果如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
-- 用户信息
DROP TABLE IF EXISTS user_info;
CREATE TABLE IF NOT EXISTS user_info (
id VARCHAR(36) NOT NULL , --ID
username VARCHAR(45) NOT NULL, --用户名
nickname VARCHAR(45) NULL, --昵称
user_type INT NOT NULL, --1管理员用户 2普通用户 3虚拟用户
avatar VARCHAR(100) NULL, --头像
register_source VARCHAR(16) NOT NULL, --注册来源:USER_NAME/PHONE/EMAIL/QQ/WECHAT/SINA_WEIBO/DOUBAN/GOOGLE/GITHUB/LINKEDIN/TWITTER/FACEBOOK
account_non_expired TINYINT NULL, --用户是否过期
account_non_locked TINYINT NULL, --用户是否被锁
credentials_non_expired TINYINT NULL, --证书是否存在
create_time DATETIME DEFAULT CURRENT_TIMESTAMP(),
update_time DATETIME DEFAULT CURRENT_TIMESTAMP(),
status VARCHAR(16) NOT NULL, --状态,ENABLED(启用),DISABLE(禁用)
enabled TINYINT DEFAULT TRUE
);
CREATE PRIMARY KEY ON user_info (id);
--用户扩展
DROP TABLE IF EXISTS user_extra;
CREATE TABLE IF NOT EXISTS user_extra (
id BIGINT AUTO_INCREMENT ,
user_id VARCHAR(36) NOT NULL
);
CREATE PRIMARY KEY ON user_extra (user_id);
--用户认证
DROP TABLE IF EXISTS user_auth;
CREATE TABLE IF NOT EXISTS user_auth (
id BIGINT AUTO_INCREMENT ,
user_id VARCHAR(36) NOT NULL,
identity_type VARCHAR(16) NOT NULL, --授权来源:USER_NAME/PHONE/EMAIL/QQ/WECHAT/SINA_WEIBO/DOUBAN/GOOGLE/GITHUB/LINKEDIN/TWITTER/FACEBOOK
identifier VARCHAR(64) NOT NULL, --手机号/邮箱/用户名或第三方应用的唯一标识
certificate VARCHAR(64) NOT NULL, --密码凭证(站内的保存密码,站外的不保存或保存token)
create_time DATETIME DEFAULT CURRENT_TIMESTAMP(),
update_time DATETIME DEFAULT CURRENT_TIMESTAMP(),
status VARCHAR(16) NOT NULL, --状态,ENABLED(启用),DISABLE(禁用)
);

以上,如果我们需要为用户添加一种认证方式,可以在user_auth表中对应添加一条记录。比如,我们需要对接微博认证,那么就直接在user_auth表中添加一条identity_type=SINA_WEIBO的数据记录。我们在登录的时候,就可以直接使用user_auth表的identity_type,identifier和certificate进行认证,从而获得到user_id,然后可以拿user_id到user_info表和user_extra表中获得更多的用户数据。

当然,这种方式也是有缺点的。最主要的缺点就是密码修改,当我们进行修改密码的时候,我们必须对手机号、邮箱以及用户名的所有的密码进行修改。还有一个缺点就是在登录时候要在程序中进行正则匹配,确定是哪种认证方式,那么匹配的顺序就很关键了。

这个也只是一种参考的实现思路,具体的情况具体分析,我们可以根据实际情况进行必要的调整和修改。


参考:

用户系统设计与实现

浅谈数据库用户表结构设计,第三方登录