第5章用户登录服务——5.4 手机号登录和邮箱登录

第5章用户登录服务——5.4 手机号登录和邮箱登录
John Yaml大部分互联网应用都支持手机号登录和邮箱登录的功能,这不仅仅使登录方式多样化,更重要的是,使用手机和邮箱往往具有如下优势。
- 用户习惯:人们在日常生活中通常使用手机和邮箱进行通信,互联网用户更是习惯使用固定的手机号或邮箱地址作为登录凭证,而不是花费心思去记住自己的各种账号与密码。
- 数据唯一:一个手机号只会属于一个用户,不存在多个用户使用同一个手机号的情况。对于邮箱也是如此。使用手机和邮箱可以免去冗长的账号注册流程,降低用户使用门槛。
- 身份认证:使用手机和邮箱能对用户进行身份认证,确保用户身份合法。
- 数据安全:手机和邮箱通常与用户数据权限关联,当用户忘记密码时,使用它们可以有效缩短找回密码的流程,提高账号的安全性。
总之,提供手机号登录和邮箱登录功能的目的是方便用户快速、安全地登录,提升用户体验,降低用户使用门槛。
5.4.1 数据表设计
为了支持以手机号、邮箱等类似方式登录的功能,在数据库中需要额外创建一个用户授权表User_auth,如表5-2所示。
User_auth表与User表是多对一的关系,且有两个索引。
- auth_id索引:根据手机号或邮箱地址查询授权记录,找到对应的用户。
- user_id索引:根据用户ID查询其手机号和邮箱。
5.4.2 用户注册
当用户使用手机号或邮箱注册账号时,需要确认用户使用的确实是自己可支配的手机号、邮箱,确认的方式就是使用验证码:用户在注册时,服务端会向对应的手机号或邮箱发送一条比如有效时间为5min的随机验证码,用户需要在这5min内提交正确的验证码才认为手机号或邮箱地址合法。使用手机号注册的流程和使用邮箱注册几乎完全一致,这里仅以手机号注册为例介绍用户注册流程。
- 用户进入注册页面,选择手机号注册方式并填入当前可用的手机号,然后点击“发送验证码”按钮。
- 用户登录服务收到请求后,先在User_auth表中查询此手机号是否已存在且被他人使用。SQL语句为
SELECT count(1) FROM User_auth WHERE auth_id='手机号' AND auth_type=1
。 - 如果此手机号未被使用,则继续注册流程:为此用户创建用户ID,在User_auth表中插入新记录。SQL语句为
INSERT INTO User_auth(auth_id, auth_type, user_id, auth_status) VALUES ('手机号', 1, 用户ID, 0)
。 - 用户登录服务生成一个随机验证码,并以String对象的形式保存到Redis中,其中Key为
telephone_{手机号}
,Value为验证码,用于保存手机号和验证码的关系。然后,调用第三方运营商的短信接口向这个手机号发送验证码。此时,用户注册请求得到响应“验证码已发送”。 - 用户收到验证短信并填入验证码,点击“注册”按钮,手机号和用户输入的验证码被发送到用户登录服务。
- 用户登录服务使用手机号在Redis中查询验证码,并与用户输入的验证码进行对比。如果用户输入的验证码和服务端下发的验证码相同,则说明用户确实是此手机号的使用者,注册流程继续。
- 用户登录服务将User_auth表中的授权状态(auth_status)改为“通过”,然后用户得到响应“请设置密码”并跳转到密码设置页面。
- 用户提交所输入的初始密码,用户登录服务在User表中插入用户账号数据,其中用户名称被默认设置为
手机用户_{手机号}
。SQL语句为INSERT INTO User(id, username, password, status, status) VALUES (用户ID, 用户名, 密码, 0)
。
至此,整个注册流程结束。
5.4.3 用户登录
使用手机号登录时分为两种方式:
- 使用手机号和账号密码登录
- 使用手机号和验证码登录
前者是比较常规的方式,免去了用户要记住用户名的痛苦,但是用户依然要记得密码;而后者更为人性化,只需要保证手机号确实为请求者所使用即可,因为需要接收验证码。
使用手机号和账号密码登录的流程如下。
- 用户输入手机号和账号密码,并点击“登录”按钮。
- 用户登录服务从User_auth表中获取手机号对应的授权用户ID。SQL语句为
SELECT user_id FROM User_auth WHERE auth_id=手机号 AND auth_type=1
。如果获取到数据,则说明此手机号已被注册。 - 用户登录服务根据查询到的用户ID,继续从User表中查询密码。SQL语句为
SELECT password FROM User WHERE id=用户ID
。然后,将查询到的密码与用户输入的密码进行对比,如果它们一致,则登录成功。
使用手机号和验证码登录的流程如下。
- 用户输入手机号,然后点击“发送验证码”按钮。
- 用户登录服务收到请求后,先在User_auth表中查询此手机号是否已被授权。SQL语句为
SELECT count(1) FROM User_auth WHERE auth_id='手机号' AND auth_type=1
。 - 如果此手机号已被授权,那么用户登录服务会生成一个随机验证码,并将其保存到Redis中(以与注册流程同样的方式),同时发送验证短信。
- 用户输入所收到的短信验证码,点击“登录”按钮。
- 用户登录服务发现用户输入的验证码与Redis中的数据相同,用户登录成功,将该用户在User表中的status更新为“1”。
虽然这里是分开介绍注册与登录流程的,但是很多互联网公司都将两者做了结合:对用户只提供登录页面,如果在登录流程中发现手机号不存在,则使用这个手机号先注册再登录,使得注册流程对用户无感,极大地简化了注册流程。
5.4.4 手机号一键登录
使用手机号登录,用户需要依次输入手机号、等待接收短信验证码、填写验证码、点击“登录”按钮,整个过程可能会花费几十秒,用户操作依然较为烦琐。而且,短信验证码常常莫名收不到,或者过了很久才收到,这会导致一批用户放弃注册、登录。那么,是否有更简单的方式可以实现手机号登录呢?
大家先回想一下,使用手机号登录为什么需要短信验证码?短信验证码的作用就是认证这个手机号你正在使用,那么是否还有其他的方式对手机号进行认证?答案是肯定的,即本机号码认证。
当用户在移动端发起登录时,应用可以获取到此时移动端设备插入的SIM卡对应的手机号,如果此号码与用户登录时填写的手机号相同,则说明此登录手机号就是用户正在使用的号码。不过,出于安全的考虑,无论是Android、iOS还是其他移动端平台,均不允许应用直接获取手机号。
幸运的是,目前主流的移动运营商都已经开放了相关能力,我们可以调用运营商提供的接口判断用户输入的手机号是否与本机号码相同,这样用户就免去了接收验证码的步骤。甚至更进一步,用户连登录手机号都不需要填写,这就是本节的主角:一键登录。
目前国内三大运营商都提供了一键登录的开放平台,比如中国电信的天翼账号开放平台、中国移动的互联网能力开放平台等。无论是哪个运营商,都提供了相似的接入一键登录能力的流程。首先,应用开发商在运营商开放平台注册应用信息并填写相关资料,待运营商审核资料通过后,为此应用下发AppKey和AppSecret(相当于运营商提供给应用开发商使用一键登录功能的权限认证)。然后,应用开发商携带AppKey和AppSecret,调用运营商接口获取本机号码相关信息。
手机号一键登录的完整流程如下所述,如图5-3所示。
- 用户登录时,客户端调用运营商SDK,传入AppKey和AppSecret完成SDK初始化工作。
- 调用运营商SDK唤起授权页。SDK从运营商那里获取手机号掩码,获取成功后跳转到授权页。授权页会显示手机号掩码以及运营商协议让用户确认,其中手机号掩码特指用星号代替手机号中间4位的形式,如
181****6738
。 - 用户同意相关协议,点击授权页面的“登录”按钮,SDK会从运营商那里获取此次取号的令牌(token),这个令牌是当前使用此手机号的唯一标识。
- 用户点击“登录”按钮后,令牌被发送到应用服务端。服务端携带此令牌,调用运营商一键登录的接口获取具体的手机号。
- 服务端使用运营商返回的手机号作为用户登录的手机号,然后执行登录流程(与5.4.3节介绍的登录流程相同)。
为了减少用户登录等待时间,通常第1步和第2步会在应用启动时就提前执行了,当用户准备登录时可以直接进入授权页。其实授权页大家都非常熟悉,它一般如图5-4所示。
一键登录的好处是显而易见的,用户不需要关心手机验证码,甚至不用主动输入手机号,就可以非常方便、快捷地完成注册与登录流程,将原本可能要花费数十秒的流程缩短到只需几秒,在很大程度上降低了注册与登录环节的用户流失。只要是使用移动端应用,且移动端设备插入SIM卡的用户,就可以享受到手机号一键登录带来的极大便利。在移动互联网高速发展的今天,满足这两个条件的用户占比极高,所以实现手机号一键登录功能的收益较大。
总结
手机号注册时的注册流程?
- 用户进入注册页面,选择手机号注册方式并填入当前可用的手机号,然后点击“发送验证码”按钮。
- 用户登录服务收到请求后,先在User_auth表中查询此手机号是否已存在且被他人使用。SQL语句为
SELECT count(1) FROM User_auth WHERE auth_id='手机号' AND auth_type=1
。 - 如果此手机号未被使用,则继续注册流程:为此用户创建用户ID,在User_auth表中插入新记录。SQL语句为
INSERT INTO User_auth(auth_id, auth_type, user_id, auth_status) VALUES ('手机号', 1, 用户ID, 0)
。 - 用户登录服务生成一个随机验证码,并以String对象的形式保存到Redis中,其中Key为
telephone_{手机号}
,Value为验证码,用于保存手机号和验证码的关系。然后,调用第三方运营商的短信接口向这个手机号发送验证码。此时,用户注册请求得到响应“验证码已发送”。 - 用户收到验证短信并填入验证码,点击“注册”按钮,手机号和用户输入的验证码被发送到用户登录服务。
- 用户登录服务使用手机号在Redis中查询验证码,并与用户输入的验证码进行对比。如果用户输入的验证码和服务端下发的验证码相同,则说明用户确实是此手机号的使用者,注册流程继续。
- 用户登录服务将User_auth表中的授权状态(auth_status)改为“通过”,然后用户得到响应“请设置密码”并跳转到密码设置页面。
- 用户提交所输入的初始密码,用户登录服务在User表中插入用户账号数据,其中用户名称被默认设置为
手机用户_{手机号}
。SQL语句为INSERT INTO User(id, username, password, status, status) VALUES (用户ID, 用户名, 密码, 0)
。
使用手机号登录时分为哪两种方式?
- 使用手机号和账号密码登录
- 使用手机号和验证码登录
使用手机号和账号密码登录的流程?
- 用户输入手机号和账号密码,并点击“登录”按钮。
- 用户登录服务从User_auth表中获取手机号对应的授权用户ID。SQL语句为
SELECT user_id FROM User_auth WHERE auth_id=手机号 AND auth_type=1
。如果获取到数据,则说明此手机号已被注册。 - 用户登录服务根据查询到的用户ID,继续从User表中查询密码。SQL语句为
SELECT password FROM User WHERE id=用户ID
。然后,将查询到的密码与用户输入的密码进行对比,如果它们一致,则登录成功。
使用手机号和验证码登录的流程?
- 用户输入手机号,然后点击“发送验证码”按钮。
- 用户登录服务收到请求后,先在User_auth表中查询此手机号是否已被授权。SQL语句为
SELECT count(1) FROM User_auth WHERE auth_id='手机号' AND auth_type=1
。 - 如果此手机号已被授权,那么用户登录服务会生成一个随机验证码,并将其保存到Redis中(以与注册流程同样的方式),同时发送验证短信。
- 用户输入所收到的短信验证码,点击“登录”按钮。
- 用户登录服务发现用户输入的验证码与Redis中的数据相同,用户登录成功,将该用户在User表中的status更新为“1”。
手机号一键登录的流程?
- 用户登录时,客户端调用运营商SDK,传入AppKey和AppSecret完成SDK初始化工作。
- 调用运营商SDK唤起授权页。SDK从运营商那里获取手机号掩码,获取成功后跳转到授权页。授权页会显示手机号掩码以及运营商协议让用户确认,其中手机号掩码特指用星号代替手机号中间4位的形式,如
181****6738
。 - 用户同意相关协议,点击授权页面的“登录”按钮,SDK会从运营商那里获取此次取号的令牌(token),这个令牌是当前使用此手机号的唯一标识。
- 用户点击“登录”按钮后,令牌被发送到应用服务端。服务端携带此令牌,调用运营商一键登录的接口获取具体的手机号。
- 服务端使用运营商返回的手机号作为用户登录的手机号,然后执行登录流程(与5.4.3节介绍的登录流程相同)。
为了减少用户登录等待时间,通常第1步和第2步会在应用启动时就提前执行了,当用户准备登录时可以直接进入授权页。