登录系统设计

登录系统设计

Posted by Hzy on April 16, 2020

1.首先思考下实现这个的登录系统的目的:

  • 1 . 能结合国内的行情,支持手机,账号,等第三方登录。
  • 2 . 易于扩展,能往多应用进行扩展。

2.主要需要解决的问题:

  • 1 . 账号体系的设计
  • 2 . 数据库表的设计
  • 3 . 登录流程的设计

2.1 思考一:账号体系的设计

这里我们主要以自建账号为主,第三方账号为辅

2.1.1:自建账号和第三方账号如何结合?

回答:无论自建账号还是第三方登录时,注册时都生成唯一的ID,这个ID不可修改,所有的第三方登录,邮箱,手机号,都绑定在此ID之下。

2.1.2:ID如何生成,如何设计,如何确保唯一?

回答:

  • 1 . 我们可以使用mysql中的自增id。 缺点
  • 2 . 使用uuid。
  • 3 . 使用Twitter使用Snowflake算法。

例子:

  • 微信登录:wechat_xxxx
  • 手机登录:phone_xxxx
  • 账号密码登录:local_xxx
  • 优点:本地生成,简单,性能好。
  • 缺点:长度比较长,不方便查询。
2.2登录流程的设计:

登录思维导图

2.3 数据库的设计

模型应该把用户的个人信息和身份区分开来,身份用于验证和登录,个人信息归于个人资料,另行处理。

个人资料表:

  • 用户唯一的ID
  • 基本信息:昵称,性别,城市,头像。
  • 微信:绑定的微信账户
  • 支付宝:绑定的支付宝账户

账号密码表:

  • 用户唯一的ID
  • 账号:大小写字母下划线数字组成
  • 密码:密码+uuid+盐 MD5加密。
  • 邮箱:符合邮箱规范。
  • 注册时间:时间戳

第三方社交登录表:

  • 用户唯一的ID
  • 第三方的识别码
  • 第三方的平台
  • 创建时间:时间戳
2.4 前后端的鉴权方式设计。

常见的几种鉴权方式

  • HTTP Basic Authentication
  • session-cookie
  • Token 验证
  • OAuth(开放授权)

这里我们选用Token验证,常用的JWT。

Token验证的好处:

  • 相比在服务端效验sessionID的有效性,TOken本身就是一种登录凭证,需要效验是否合法即可。
  • 相比cookies-session,Token验证支持更多的客户端类型。
  • 更易于扩展。
2.4.1 Jwt验证会遇到的几个问题:

废除问题:

  • Token一旦签发了,在有效期内都可以使用,服务端无法终止和废除。

    续签问题:

  • 无法像session那样, 自动更新sessionID的有效期。

解决方法是:参考OAuth2中个的refreshToken,允许客户端主动刷新Access Token

jwt流程

流程:

  • 客户端首先进行认证。
  • 服务端效验后 ,生成两个Token:Access Token 和Refresh Token,一个有效期短,一个有效期长。
  • 客户端访问受限资源时,携带access Token,进行鉴权。
  • 如果Access Token 没有过期,则返回数据。
  • 如果Access Token 过期,通知客户端使用Refresh请求刷新接口,刷新accessToken。
  • 如果Refresh Token 没有过期,服务端下方新的Access Token,客户端通过新的Access Token 请求数据。
  • 如果Refresh Token 过期,同时access Token也过期,那么让用户重新登录。

这样的好处在于,用户不会频繁的隔几个小时就需要登录一次,但Refresh Token有效时长是固定的,假设是两周,那么用户两周就需要登录一次。

对Refresh Token的改进

  • 可以在用每次请求更换Access Token时,判断Refresh Token的剩余时长,若小于25%,则延长一个Access Token的时间。

如何同一时间,允许在一个设备登录?

  • 我们在缓存中维护一个黑名单表,同时jti是每个token的唯一标识符。
  • 新设备登录时,更换Token的时候把旧的Token加入到黑名单中。
  • 旧的token请求时,由于在黑名单表中,判定为无效。

定时清理黑名单中过期的Token,防止缓存表太大。

参考文章