设计一个可扩展的用户登录系统

在Web系统中,用户登录是最基本的功能。要实现用户名+密码登录,很多同学的第一想法就是直接创建一个Users表,包含usernamepassword两列,这样,就可以实现登录了:

 id | username | password | name等其他字段----+----------+----------+----------------
 A1 | bob      | a1b23f2c | ...
 A2 | adam     | c0932f32 | ...

现在问题来了,如果要让用户通过第三方登录,比如微博登录或QQ登录,怎么集成进来呢?

以微博登录为例,由于微博使用OAuth2协议登录,所以,一个登录用户会包含他的微博身份的ID,一个Access Token用于代表该用户访问微博的API和一个过期时间。

要集成微博登录,很多童鞋立刻想到把Users表扩展几列,记录下微博的信息:

 id | username | password | weibo_id | weibo_access_token | weibo_expires | name等其他字段----+----------+----------+----------+--------------------+---------------+----------------
 A1 | bob      | a1b23f2c | W-012345 | xxxxxxxxxx         | 604800        | ...
 A2 | adam     | c0932f32 | W-234567 | xxxxxxxxxx         | 604800        | ...

加一个QQ登录Users表就又需要加3列,如果这么扩展下去,改表都得累死,不要说维护代码了。

那怎么才能设计出灵活的登录呢?

不妨换个角度考虑用户登录。当用户以任意一种方式登录成功后,我们读取到的总是Users表对应的一行记录,它实际上是用户的个人资料(Profile),而登录过程只是为了认证用户(Authenticate),无论是本地用密码验证,还是委托第三方登录,这个过程本质上都是认证。

所以,如果把Profile和Authenticate分开,就十分容易理解了。Users表本身只存储用户的Profile:

 id | name | birth等其他字段----+------+-----------------
 A1 | Bob  |  ...
 A2 | Adam | ...

而通过用户名口令登录可视为一种Authenticate的方式,利用LocalAuth表维护:

 id | user_id | username | password----+---------+----------+-----------
 01 | A1      | bob      | a1b23f2c
 02 | A2      | adam     | c0932f32

通过微博登录可视为另一种Authenticate方式,利用OAuth表维护:

 id | user_id | weibo_id | weibo_access_token | weibo_expires----+---------+----------+--------------------+---------------
 11 | A1      | W-012345 | xxxxxxxxxx         | 604800
 12 | A2      | W-234567 | xxxxxxxxxx         | 604800

如果要添加另一种OAuth登录,比如QQ登录,增加一个表就可以了。不过既然大家都是OAuth家族的,不如统一到一个表,给每家起个名字区分就好了:

 id | user_id | oauth_name | oauth_id | oauth_access_token | oauth_expires----+---------+------------+----------+--------------------+---------------
 11 | A1      | weibo      | W-012345 | xxxxxxxxxx         | 604800
 12 | A2      | weibo      | W-234567 | xxxxxxxxxx         | 604800
 13 | A1      | qq         | Q-090807 | xxx-xxx-xxx        | 86400
 14 | A2      | qq         | Q-807060 | xxx-xxx-xxx        | 86400

如果要增加一种新的登录方式,比如SAML,那就再加一种类型的表。

有些网站需要API访问,API可以使用api_key和api_secret来认证,可是怎么把一个API访问关联到一个用户?方法还是增加一种API Auth的表:

 id | user_id | api_key  | api_secret----+---------+----------+------------
 11 | A1      | a-012345 | xxxxxxxxxx
 12 | A2      | a-234567 | xxxxxxxxxx

每一种X-Auth表都存储了用户的登录认证信息,并通过user_id关联到Users表。这样一来,不但登录过程简化了,而且一个用户可以使用多种方式登录。只要登录成功,拿到了user_id,最后读取Users表是为了获得用户的Profile,这样读出来的数据也更安全,因为Users表不包含用户口令,不会因为暴露API而不小心把口令给泄露出去。

原文发布于微信公众号 - php(phpdaily)

原文发表时间:2015-11-20

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏FreeBuf

开发者误读芯片厂商调试文档,导致主要操作系统均出现新内核漏洞

美国计算机安全应急响应中心(以下简称“CERT”)日前发布公告称,Windows、macOS、Red Hat、Ubuntu、SUSE Linux、FreeBSD...

1005
来自专栏FreeBuf

魔波广告恶意病毒简析

1.病毒介绍 魔波广告恶意病毒通过仿冒浏览器,播放器和一些游戏等进行传播,一旦用户手机不慎被感染,该病毒将立即下载提权文件来获取 root权限,频繁推送广告,监...

2035
来自专栏文渊之博

迁移数据库数据到SQL Server 2017

概述 本篇我们将利用DMA一步一步实现SQL Server 的迁移。帮助大家理解现在的SQL Server与新版本的融合问题,同时需要我们做哪些操作来实现新版本...

3766
来自专栏Jerry的SAP技术分享

如何将SAP Multi Target应用部署到SAP云平台的Cloud Foundry环境去

SHINA是SAP HANA Interactive Education的缩写,是一个demo应用,用于演示如何开发SAP HANA原生应用。

3797
来自专栏娱乐心理测试

关于小程序的一些基本常识

    a. 如果小程序需要与你的服务器进行数据交换,那么你就必须注册域名,即使是开发环境也需要;

753
来自专栏北京马哥教育

从苦逼到牛逼,详解Linux运维工程师的打怪升级之路

做运维也快四年多了,就像游戏打怪升级,升级后知识体系和运维体系也相对变化挺大,学习了很多新的知识点。 运维工程师是从一个呆逼进化为苦逼再成长为牛逼的过程,前提在...

3944
来自专栏北京马哥教育

请注意!Zabbix高危SQL注入漏洞分析

? 0x01 漏洞概述 zabbix是一个开源的企业级性能监控解决方案。近日,zabbix的jsrpc的profileIdx2参数存在insert方式的SQL...

2967
来自专栏大魏分享(微信公众号:david-share)

一个虚拟化客户上云的需求分析&架构设计-大卫的Azure学习笔记大全

案例分析与架构设计 案例分析:大卫公司电子商务网站案例研究 大卫公司是北京的一家媒体和出版公司,拥有约2000名员工。它有一个成功的直接面向消费者的电子商务网站...

3578
来自专栏.Net移动开发

4.6预告先导篇——你们关心的几个问题:关于页、文档、内网推送等

非常感谢大家对Smobiler的支持,从4.6版本的建议征集中,整理了几个大家关注得比较多的问题,在此单独列出答复。

792
来自专栏Guangdong Qi

iOS APP版本构建版本无效

1833

扫码关注云+社区