点击上方蓝色字体,选择“标星公众号”
优质文章,第一时间送达
关注公众号后台回复pay或mall获取实战项目资料+视频
来源:www.dustyblog.cn
现在几乎大部分的 App
都支持使用多个第三方账号进行登录,如:微信、QQ、微博等,我们把此称为多账号统一登陆。而这些账号的表设计,流程设计至关重要,不然后续扩展性贼差。
本文不提供任何代码实操,但是梳理一下博主根据我司账号模块的设计,提供思路,仅供参考。
该设计的思路是每个手机号对应一个用户,手机号为必填项。
流程:
首先输入手机号,然后发送到服务端。先判断该手机号是否存在账号,如果没有,就会生成随机验证码,将手机号和验证码绑定到 Redis
中,并设置一定的过期时间(过期时间一般是5分钟,这就是我们一般手机验证码的有效期),最后将验证码通过短信发送给用户。
用户接收到验证码后,在界面填写验证码以及密码等基础信息,然后将这些数据发送服务端。服务端收到后,先判断在 Redis
里面这个手机号对应的验证码是否一致,,失败就返回错误码,成功就给用户创建一个账号和保存密码。
注册成功后,用户即可通过自己的 手机号+密码
进行登陆。
问题:
用户体验差,需要完成获取验证码,填写验证码/密码/用户名等诸多的信息完成注册,然后才能使用;
容易遗忘密码,遗忘后,只能通过忘记密码来重新设置密码。
该方案的思路是弱化密码的必填性,即无论用户是否注册过,可通过
手机号+验证码
直接进行登陆(保留手机号+密码
登录的方式)。
流程:
输入手机号,然后发送到服务端。服务端生成随机验证码,将手机号和验证码绑定到 Redis
中,并设置一定的过期时间(过期时间一般是5分钟,这就是我们一般手机验证码的有效期),最后将验证码通过短信发送给用户。
用户接收到验证码后,在界面只需填写收到的验证码,提交到服务端。服务端收到后,先判断在 Redis
里面这个手机号对应的验证码是否一致,失败就返回错误码,成功就直接登录。如果是老用户,直接拉取用户信息;如果是新用户,则提示他可以完善用户信息(不强制)。
用户通过 手机号+验证码
登录后,也可选择设置密码,然后就可以通过 手机号+密码
的方式登录,即:密码是非必填项。
用户表设计:
id | user_name | user_password | user_mobile | state | more |
---|---|---|---|---|---|
用户id | 用户名 | 用户密码 | 手机号码 | 账号状态 | 其他信息 |
进入 Web2.0
时代 ,微博开放了第三方网站登录, 产品说, 这个我们得要, 加个用微博帐号就能登录我们的 App
吧,而且得和我们自己的用户表关联。
流程:
客户端调用微博登录的界面,进行输入用户名、密码,登录成功后,会返回 access_token
,通过 access_token
调取 API
接口获取用户信息。
服务端通过用户信息在我们用户表创建一个账号,以后,该第三方账号即可通过该微博账号直接进行登陆。
微博用户信息表设计:
id | user_id | uid | access_token |
---|---|---|---|
主键id | 用户id | 微博唯一id | 授权码 |
紧接着, QQ又开放用户登录了, 微信开放用户登录了,网易开发用户登录了。。。。。。一下子要接入好多家第三方登录了, 只能按照 “微博用户信息表” 新建一个表,重写一套各个第三方登录。
自建登陆体系:无论 手机号+密码
, 还是 手机号+验证码
, 都是一种 用户信息+密码
的验证形式;
第三方登录:也是 用户信息+密码
的形式, 用户信息即第三方系统中的 ID
(第三方系统中的唯一标识), 密码即 access_token
, 只不过是一种有使用时效定期修改的密码。
用户基础信息表:
id | nickname | avatar | more |
---|---|---|---|
用户id | 昵称 | 头像 | 其他信息 |
用户授权信息表:
id | user_id | identity_type | identifier | credential |
---|---|---|---|---|
主键id | 用户id | 登录类型(手机号/邮箱) 或第三方应用名称 (微信/微博等) | 手机号/邮箱/第三方的唯一标识 | 密码凭证 (自建账号的保存密码, 第三方的保存 token) |
说明:
用户表分为 用户基础信息表
+ 用户授权信息表
;
用户信息表不保存任何密码, 不保存任何登录信息(如用户名, 手机号, 邮箱), 只留有昵称、头像等基础信息; 所有和授权相关,都放在用户信息授权表, 用户信息表和用户授权表是一对多的关系 。
手机号+验证码
沿用之前的方案。
邮箱/手机号+密码
:
用户填写 邮箱/手机号+密码
; 请求登录的时候, 先判断类型, 如手机号登录为例:
使用 type='phone'
结合 identifier='手机号'
查找, 如有, 取出并判断 password_hash
(密码)是否和该条目的 credential
相符, 相符则通过验证, 随后通过 user_id
获取用户信息;
第三方登录, 如微信登录:
查询 type='weixin'
结合 identifier='微信 openId'
, 如果有记录, 则直接登录成功, 并更新 token
; 假设与微信服务器通信不被劫持的情况下无需判断凭证问题。
优点:
登录类型无限扩展, 新增登录类型的开发成本显著降低;
原来条件下, 应用需要验证手机号是否已验证和邮箱是否已验证, 需要相对应多一个字段如 phone_verified
和 email_verified
, 如今只要在 用户授权信息表
表中增加一个统一的 verified
字段, 每种登录方式都可以直观看到是否已验证情况;
在 用户授权信息表
添加相应的时间和 IP
地址, 就可以更加完整地跟踪用户的使用习惯, 比如:已经不使用微博登录两年多, 已经绑定微信 300天;
如果你说邮箱和手机号就是用户信息的组成部分, users 表尽管拓展, users 表里依然有email , phone , 但他们仅仅作为“展示用途”,和昵称,头像或者性别这些属性没有本质区别;
可按需绑定任意数量的同类型登录方式, 即一个用户可以绑定多个微信, 可以有多个邮箱, 可以有多个手机号。当然你也可以限制一种登录方式只有一条记录;
缺点 :
用户同时存在邮箱、用户名、手机号等多种站内登录方式时, 改密码时必须一起改, 否则就变成了 邮箱+新密码
, 手机号+旧密码
都可以登录, 肯定是很诡异的情况;
代码量增加了, 有些情况下逻辑判断增加了, 难度增大了; 举个例子, 无论用户是否已登录, 无论用户是否已注册过, 都是点击同一链接前往微博第三方授权后返回, 可能出现几种情况:
该微博在本站未注册过, 很好, 直接给他注册关联并登录;
该微博已经在本站存在, 当前用户未登录, 直接登录成功;
该微博未在本站注册, 但当前用户已经登录并关联的是另一个微博帐号, 作何处理取决于是否允许绑定多个微博帐号;
该微博未在本站注册过, 当前用户已登录, 尝试进行绑定操作;
该微博已经注册, 用户又已使用该帐号登录, 为何他重复绑定自己;
该微博已经在本站存在, 但当前用户已经登录并关联的是另一个微博帐号, 作何处理?
回顾一下 手机号+验证码
的登录方式:
输入手机号、等待验证码短信、输入验证码、点击登录。整个流程走完可能需要 20 秒以上,操作也比较繁琐;
它是依赖短信网络的,因为如果收不到短信,也就登录不了了。
从安全角度考虑,还存在验证码泄漏的风险。如果有人知道了你的手机号,并且窃取到了验证码,那他也能登录你的账号了。
但回过头来想一下,为什么我们需要验证码?验证码的作用就是确定这个手机号是你的,那除了使用短信,是否还有别的方式对手机号进行认证?
如果能获取到当前使用的手机号,就能对用户输入的号码进行验证了。但出于安全考虑,客户端是无法直接获取到手机号的,运营商则可以通过 SIM
卡数据查询到。
现在运营商已经开放了相关的能力,现在我们可以在用户输入手机号后,通过调用运营商的接口,判断用户输入的手机号是否和本地号码一致。这样一来,用户就省去了等待验证码短信、输入验证码的过程,也不受短信网络的限制,简化了登录流程。
但再进一步想,如果运营商可以把当前的号码直接返回给我们,而不只是用于验证,那用户连手机号都不需要填了。
这就是该部分的主角:一键登录 。
获取到当前手机使用的手机卡号,直接使用这个号码进行登录,这就是一键登录。
这种登录方式的好处是显而易见的。它可以更方便、快捷地完成注册、登录流程,将原本可能需要 20 秒的流程,缩短到了 2 秒左右,很大程度上提升了登录的用户体验。
主要步骤如下:
SDK 初始化:调用 SDK 的初始化方法,传入项目在平台上的 AppKey 和 AppSecret。
唤起授权页:调用 SDK 唤起授权接口。SDK 会先向运营商发起获取手机号验码的请求,请求成功后跳转到授权页。授权页会显示手机号掩码以及运营商协议给用户确认。
同意授权并登录:用户同意相关协议,点击授权页面的登录按钮,SDK 会请求本次取号的 token,请求成功后将 token 返回给客户端。
取号:将获取到的 token 发送到我们自己的服务器,由服务器携带 token 调用运营商一键登录的接口,调用成功就返回手机号码了。服务器用手机号进行登录或注册操作,返回操作结果给客户端,完成一键登录。
目前阿里云已经提供了该方式并可兼容三大运营商的号码,详见 阿里云SDK:
https://help.aliyun.com/document_detail/121113.html
博主看来,没有最好的方案,选择适用当前系统的设计即可。不要深究孰优孰劣,鞋合不合脚,只有脚知道。
有热门推荐
你在 Docker 中跑 MySQL?恭喜你,可以滚了!
头条三面:toString()、String.valueOf、(String)强转,有啥区别?
0.2秒居然复制了100G文件?
最牛逼的 Java 日志框架,性能无敌,横扫所有对手.....
50 个 经典 Spring 面试题
笑出腹肌的注释,都是被代码耽误的诗人!
手写了一个简单的JSON解析器,网友直乎:牛!
Docker镜像瘦身:从1.43G到22.4MB
IDEA 搞酷点!
文章浏览阅读3.4k次,点赞8次,收藏42次。一、什么是内部类?or 内部类的概念内部类是定义在另一个类中的类;下面类TestB是类TestA的内部类。即内部类对象引用了实例化该内部对象的外围类对象。public class TestA{ class TestB {}}二、 为什么需要内部类?or 内部类有什么作用?1、 内部类方法可以访问该类定义所在的作用域中的数据,包括私有数据。2、内部类可以对同一个包中的其他类隐藏起来。3、 当想要定义一个回调函数且不想编写大量代码时,使用匿名内部类比较便捷。三、 内部类的分类成员内部_成员内部类和局部内部类的区别
文章浏览阅读118次。分布式系统要求拆分分布式思想的实质搭配要求分布式系统要求按照某些特定的规则将项目进行拆分。如果将一个项目的所有模板功能都写到一起,当某个模块出现问题时将直接导致整个服务器出现问题。拆分按照业务拆分为不同的服务器,有效的降低系统架构的耦合性在业务拆分的基础上可按照代码层级进行拆分(view、controller、service、pojo)分布式思想的实质分布式思想的实质是为了系统的..._分布式系统运维工具
文章浏览阅读174次。1.数据源准备2.数据处理step1:数据表处理应用函数:①VLOOKUP函数; ② CONCATENATE函数终表:step2:数据透视表统计分析(1) 透视表汇总不同渠道用户数, 金额(2)透视表汇总不同日期购买用户数,金额(3)透视表汇总不同用户购买订单数,金额step3:讲第二步结果可视化, 比如, 柱形图(1)不同渠道用户数, 金额(2)不同日期..._exce l趋势分析数据量
文章浏览阅读3.3k次。堡垒机可以为企业实现服务器、网络设备、数据库、安全设备等的集中管控和安全可靠运行,帮助IT运维人员提高工作效率。通俗来说,就是用来控制哪些人可以登录哪些资产(事先防范和事中控制),以及录像记录登录资产后做了什么事情(事后溯源)。由于堡垒机内部保存着企业所有的设备资产和权限关系,是企业内部信息安全的重要一环。但目前出现的以下问题产生了很大安全隐患:密码设置过于简单,容易被暴力破解;为方便记忆,设置统一的密码,一旦单点被破,极易引发全面危机。在单一的静态密码验证机制下,登录密码是堡垒机安全的唯一_horizon宁盾双因素配置
文章浏览阅读7.7k次,点赞4次,收藏16次。Chrome作为一款挺不错的浏览器,其有着诸多的优良特性,并且支持跨平台。其支持(Windows、Linux、Mac OS X、BSD、Android),在绝大多数情况下,其的安装都很简单,但有时会由于网络原因,无法安装,所以在这里总结下Chrome的安装。Windows下的安装:在线安装:离线安装:Linux下的安装:在线安装:离线安装:..._chrome linux debian离线安装依赖
文章浏览阅读153次。中国发达城市榜单每天都在刷新,但无非是北上广轮流坐庄。北京拥有最顶尖的文化资源,上海是“摩登”的国际化大都市,广州是活力四射的千年商都。GDP和发展潜力是衡量城市的数字指...
文章浏览阅读3.3k次。前言spark在java使用比较少,多是scala的用法,我这里介绍一下我在项目中使用的代码配置详细算法的使用请点击我主页列表查看版本jar版本说明spark3.0.1scala2.12这个版本注意和spark版本对应,只是为了引jar包springboot版本2.3.2.RELEASEmaven<!-- spark --> <dependency> <gro_使用java调用spark注册进去的程序
文章浏览阅读4.8k次。汽车零部件开发工具巨头V公司全套bootloader中UDS协议栈源代码,自己完成底层外设驱动开发后,集成即可使用,代码精简高效,大厂出品有量产保证。:139800617636213023darcy169_uds协议栈 源代码
文章浏览阅读4.6k次,点赞20次,收藏148次。AUTOSAR基础篇之OS(下)前言首先,请问大家几个小小的问题,你清楚:你知道多核OS在什么场景下使用吗?多核系统OS又是如何协同启动或者关闭的呢?AUTOSAR OS存在哪些功能安全等方面的要求呢?多核OS之间的启动关闭与单核相比又存在哪些异同呢?。。。。。。今天,我们来一起探索并回答这些问题。为了便于大家理解,以下是本文的主题大纲:[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JCXrdI0k-1636287756923)(https://gite_autosar 定义了 5 种多核支持类型
文章浏览阅读2.2k次,点赞6次,收藏14次。原因:自己写的头文件没有被加入到方案的包含目录中去,无法被检索到,也就无法打开。将自己写的头文件都放入header files。然后在VS界面上,右键方案名,点击属性。将自己头文件夹的目录添加进去。_vs2013打不开自己定义的头文件
文章浏览阅读3.3w次,点赞80次,收藏342次。此时,可以将系统中所有用户的 Session 数据全部保存到 Redis 中,用户在提交新的请求后,系统先从Redis 中查找相应的Session 数据,如果存在,则再进行相关操作,否则跳转到登录页面。此时,可以将系统中所有用户的 Session 数据全部保存到 Redis 中,用户在提交新的请求后,系统先从Redis 中查找相应的Session 数据,如果存在,则再进行相关操作,否则跳转到登录页面。当数据量很大时,count 的数量的指定可能会不起作用,Redis 会自动调整每次的遍历数目。_redis命令
文章浏览阅读449次,点赞3次,收藏3次。URP的设计目标是在保持高性能的同时,提供更多的渲染功能和自定义选项。与普通项目相比,会多出Presets文件夹,里面包含着一些设置,包括本色,声音,法线,贴图等设置。全局只有主光源和附加光源,主光源只支持平行光,附加光源数量有限制,主光源和附加光源在一次Pass中可以一起着色。URP:全局只有主光源和附加光源,主光源只支持平行光,附加光源数量有限制,一次Pass可以计算多个光源。可编程渲染管线:渲染策略是可以供程序员定制的,可以定制的有:光照计算和光源,深度测试,摄像机光照烘焙,后期处理策略等等。_urp渲染管线