文章前的一些声明。
1、我本人其实没啥编程基础,唯一会的代码是print 'hello world'
2、为什么会涉及到这个用户管理体系其实是因为我在尝试用AI 进行应用前后端开发,目前产品的前后端已经基本跑通,只涉及到一些小地方的调整,但考虑到后面使用多端框架开发的纯小白可能会越来越多,所以把自己的实现逻辑发出来作为记录,也是抛砖引玉,希望大佬们能帮我看下目前的实现逻辑有没有错漏的地方。
业务是个多端项目。实际上针对不同平台会有不同的登录方式处理。目前规划会有两个平台:
- 微信小程序(下称小程序)
- IOS(下称APP)
这里面有个大前提,我们的整套用户管理体系都是基于微信小程序多端框架提供的身份管理逻辑来的,根据微信官方的文档,多端身份管理基于微信身份管理体系提供的user_id,但这里有个问题。多端身份管理并不提供小程序内的登录方式,只在多端app里生效。在这种前提下,我们需要基于多端框架的身份管理体系重新构建一套完整的用户管理体系。
这套体系在小程序与app端登录方式不同,但我们尝试通过users表中的不同字段将其关联起来,由此构建一个完整的身份管理体系。但无论是哪种登录方式,我们都会在前置认证环节走完后用jwt方式生成token(包括refresh token),并返回给客户端。由此达到构建用户登录态的目的。
> 注意:用户表中存在两个字面意思的userid。一个是用户表中的自增id(列名为`id`),一个是多端用户管理体系中的user_id(列名为`user_id`)。当我们使用 **用户id** 表述时指的是自增id,当我们使用 **user_id** 表述时指的是多端用户管理体系中的user_id。 **用户id**用来满足服务业务中的关联查询等需求,**user_id** 用来满足多端用户管理体系中的用户管理需求。
小程序端
在小程序端,我们提供两种方式来实现登录
`wx.login` 登录
前端通过wx.login获取微信的登录code并发给后端,后端服务走 `code2Session` 用code换取 openid、unionid,然后在此基础上生成token返回给前端构建登录态。
手机号登录+`wx.login`登录
需要重点说明下,这里前端其实是两个步骤
步骤1:前端调用手机号快速验证组件也就是 `bindgetphonenumber` 获取手机号code
步骤2:前端调用 `wx.login` 获取微信登录code
步骤3:前端将手机号的code和微信的登录code发给后端,后端服务先走`code2Session` 用wx.login传回来的code换取 openid、unionid,然后再走 `getPhoneNumber` 用手机号的code换取手机号信息,然后用 `code2Session` 用手机号的code换取手机号。
- 步骤3中,先检查手机号是否在users表中存在,如果存在则开始构建登录态。
- 如果手机号在users表中不存在,则使用传回来的 `unionid` 创建新用户,同时给这个账户绑定当前手机号,然后开始构建登录态。
APP端
APP端和小程序端实现稍有不同,重点在于APP端登陆时,服务端使用的是 `code2Verifyinfo` 来换取用户标识信息,这个标识信息在不同登录接口下将返回不同的登录信息,且针对绑定情况,返回信息也会有所不同(见 code2Verifyinfo 板块)
在app端,我们提供3种登录方式
- 微信APP登录
- 苹果登录
- 手机号登录
微信APP登录:`wx.weixinAppLogin`
前端通过 `wx.weixinAppLogin` 获取微信的登录code,然后后端服务走 `code2Verifyinfo` 用code换取用户标识信息,然后在此基础上生成token返回给前端构建登录态。
1. 获取标识信息后,检查`unionid`是否在users表中存在,如果存在则检查`user_id`是否在users表中存在:
- 如果`user_id`存在,则开始构建登录态。
- 如果`user_id`不存在,则使用`unionid`创建新用户,同时将获取到的其他用户标识信息写入到用户表中(`user_id`、`logintype`、`login_time`)
2. 如果`unionid`在users表中不存在,则使用`unionid`创建新用户,同时将获取到的其他用户标识信息写入到用户表中(`user_id`、`logintype`、`login_time`)
苹果登录:`wx.appleLogin`
前端通过 `wx.appleLogin` 获取苹果的登录code,然后后端服务走 `code2Verifyinfo` 用code换取用户标识信息,然后在此基础上生成token返回给前端构建登录态。
1. 获取标识信息后,检查`user_id`是否在users表中存在,如果存在则开始构建登录态。
2. 如果`user_id`在users表中不存在,则使用`user_id`创建新用户。
手机号登录
手机号登录前端会有两种方式
- 本机号码一键登录:`wx.phoneOneClickLogin`
- 手机号验证码登录:`wx.phoneSmsLogin`
两种方式只是前端在获取code的方式不同,需要为两种code设计不同接口即可,走 `code2Verifyinfo` 用code换取的用户标识信息是一样的,下方只讲获取标识信息后的处理逻辑
1. 获取标识信息后,要判断当前是否返回了其他登录方式(`openapp_info`、`apple_info`)的标识信息,如果没返回其他登录方式的标识信息,则检查手机号是否在users表中存在:
- 如果手机号在users表中存在,则开始构建登录态,并返回「该手机号此前绑定过小程序,已使用绑定账号登录」同时将获取到的其他用户标识信息写入到用户表中(`user_id`、`logintype`、`login_time`)
- 如果手机号在users表中不存在,则使用`user_id`创建新用户。
2. 如果返回了其他登录方式(`openapp_info`、`apple_info`)的标识信息,则直接使用返回的信息构建用户登录态即可。
最后附上完整的用户登录流程图