小程序/移动端登录
1、应用的安全模式
- 关闭
无需登录
- 企业空间管理
归属于平台管理
- 第三方管理
第三方自定义登录,平台只保存一下信息
- SSO
SSO 平台管理,同上
针对以上 4 种情况,【关闭】无需登录,【第三方管理】【SSO】平台无法控制其是否登录以及登录状态,以下仅讨论【企业空间管理】模式下小程序/移动端登录的场景。
2、功能说明
在【企业空间管理】模式下,可开启三方移动端集成功能,如下图所示
开启后支持配置集成的移动端类型以及认证相关的配置项
- 微信小程序类型:
- AppID(小程序 ID):小程序应用 ID
- AppSecret(小程序密钥):小程序应用密码
- 蓝信应用类型:
- AppID(应用 ID):蓝信平台的应用唯一标识
- AppSecret(应用密钥):蓝信平台的应用的永久密钥
- 前端 JS-SDK 调用开关:前端页面是否初始化注入配置信息,以支持前端调用蓝信平台 SDK
- ICE 类型
ps:ICE 为国家能源集团的协同办公软件
- AppID(应用 ID):ICE 平台的应用唯一标识
- host:配置集成的 ICE 软件的环境 HOST 信息
以上三种类型中,对接蓝信应用类型和 ICE 类型时,在本平台发布应用后,获取到访问链接,在蓝信或 ICE 的后台配置地址即可;微信小程序的技术对接说明参考下文。
3、微信小程序登录流程说明
3.1、登录流程时序
3.2、简化时序图
3.3、登录模式
3.3.1、微信 JSCODE 直接登录
用户微信唯一对应平台账号,当根据 JSCODE 从微信平台登录成功后,根据 openId 寻找对应平台账号,自动登录,并将 openId 以及平台登录成功后的 access_token 一起返回给前端;若不存在对应账号,则默认生成一个新账号登录。
3.3.2、平台账号密码登录
微信登录与平台登录不做强绑定,根据 JSCODE 从微信平台登录成功后,服务端将 openId 返回前端,前端跳转平台应用的登录页面,用户可以输入平台账号密码登录。
4、相关 API
https://developers.weixin.qq.com/miniprogram/dev/OpenApiDoc/mp-access-token/getAccessToken.html
https://developers.weixin.qq.com/miniprogram/dev/OpenApiDoc/user-info/phone-number/getPhoneNumber.html
https://developers.weixin.qq.com/miniprogram/dev/OpenApiDoc/user-login/code2Session.html
5、技术方案
5.1、接口规范
5.1.1、code 登录接口
/miniProgram/login
请求方式:POST
请求参数
名称 | 父级 | 类型 | 必选 | 中文名 | 说明 |
---|---|---|---|---|---|
code | String | 是 | 授权 code 码 | wx.login()调取 code | |
grantType | String | 是 | 登录方式 | 值:wechat_code | |
instanceId | String | 是 | 应用实例 ID | 平台应用发布的实例 ID,需要根据此 id 获取登录相关的配置信息 | |
createIfNotExist | Boolean | 否 | 是否自动创建不存在的用户 | true:创建 false:不创建 不传默认 false |
{
"code": "1234",
"grantType": "wechat_code",
"instanceId": "57cd4d89a2c14a0c9ae9eff81a93eb3d",
"createIfNotExist": <strong>false</strong>
}
返回数据
名称 | 父级 | 类型 | 必选 | 中文名 | 说明 |
---|---|---|---|---|---|
status | Number | 是 | 请求执行状态 | 成功 200 | |
message | String | 否 | 消息 | 异常信息 | |
success | Boolean | 是 | 是否请求成功 | ||
data | Object | 是 | 返回数据 | ||
existUser | data | Boolean | 是 | 是否存在用户 | |
userId | data | Long | 否 | 用户 ID | 当 existUser 为 true 时返回 |
accessToken | data | String | 否 | token | 当 existUser 为 true 时返回 |
expiresIn | data | Long | 否 | 失效时间(秒) | 当 existUser 为 true 时返回 |
refreshToken | data | String | 否 | refreshToken | 当 existUser 为 true 时返回 |
tokenType | data | String | 否 | bearer | 当 existUser 为 true 时返回 |
{
"code": 200,
"success": <strong>true</strong>,
"errorCode": <strong>null</strong>,
"msg": "执行成功~~",
"data": {
"existUser": <strong>true</strong>,
"accessToken": "7e7a337e-a0ee-479b-a74c-d7812a8332f0",
"tokenType": "bearer",
"expiresIn": 43200,
"refreshToken": "642dbcec-1afe-4c02-9d79-487bd9499b19",
"userId": 2989103744245760
}
}
5.1.2、发送手机验证码
/miniProgram/sendCode
请求方式:POST
请求参数
名称 | 父级 | 类型 | 必选 | 中文名 | 说明 |
---|---|---|---|---|---|
number | String | 是 | 手机号 | ||
needImageCode | Boolean | 否 | 是否图片验证码 | true: 是 null 或者 false:否 |
{
"number": "18626307247",
"needImageCode": true
}
返回数据
名称 | 父级 | 类型 | 必选 | 中文名 | 说明 |
---|---|---|---|---|---|
status | Number | 是 | 请求执行状态 | 成功 200 | |
message | String | 否 | 消息 | 异常信息 | |
success | Boolean | 是 | 是否请求成功 | ||
data | Object | 是 | 返回数据 | ||
success | data | Boolean | 是 | 是否发送成功 | |
image | data | String | 否 | 验证码图片 | 部分需要图片验证码的场景会返回图片 base64 编码 |
{
"code": 200,
"success": <strong>true</strong>,
"errorCode": <strong>null</strong>,
"msg": "执行成功~~",
"data": {
"image": "/9j/4AAQSkZJRgABAgAAAQABAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0a\nHBwgJC4nICIsIxwcKDcpLDAxNDQ0Hyc5PTgyPC4zNDL/2wBDAQkJCQwLDBgNDRgyIRwhMjIyMjIy\nMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjL/wAARCAA8AKADASIA\nAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQA\nAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3\nODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWm\np6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEA\nAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSEx\nBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElK\nU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3\nuLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwDU8L+G\nNAuPCejTTaHpkksljA7u9pGWZiikkkjkmtceEfDf/QvaT/4BR/4UnhH/AJE3Q/8AsH2//ota0b/U\nLXSrCa+vZhDbQrukc84H4UAUh4R8Nf8AQvaT/wCAUf8A8TTh4Q8Nf9C7pP8A4BR//E0aP4l0rW9I\nj1OzuV+ztkHzCFZCOoYdjWHq3xT8MaTKYjeG5lHVbddwH49KAN8eEPDP/Qu6R/4BR/8AxNOHg/wx\n/wBC5pH/AIAx/wDxNJofiWx1zRk1SBjFbtnmX5cYpX8X+HoiQ+sWYx1xKDQA4eDvDH/QuaR/4Axf\n/E08eDvC/wD0Lej/APgDF/8AE0r+JdKXSZ9SivI57aBC7tEwbgfSua0v4weFdQnEUlzJaMTgG4Ta\n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\nlSRmQjOD6GgD/9k=",
"success": <strong>false</strong>
}
}
5.1.3、绑定手机号登录
/miniProgram/login
请求方式:POST
请求参数
名称 | 父级 | 类型 | 必选 | 中文名 | 说明 |
---|---|---|---|---|---|
code | String | 是 | 授权 code 码 | wx.login()调取 code | |
grantType | String | 是 | 登录方式 | 值:wechat_code_binding_phone | |
instanceId | String | 是 | 应用实例 ID | 平台应用发布的实例 ID,需要根据此 id 获取登录相关的配置信息 | |
createIfNotExist | Boolean | 否 | 是否自动创建不存在的用户 | true:创建 false:不创建 不传默认 false | |
needCheckCaptcha | Boolean | 否 | 是否校验验证码 | true:创建 false:不创建 不传默认 false | |
phoneNumber | String | 是 | 手机号 | 手机号 | |
captcha | String | 否 | 验证码 |
{
"code": "1234",
"grantType": "wechat_code_binding_phone",
"instanceId": "57cd4d89a2c14a0c9ae9eff81a93eb3d",
"phoneNumber": "18626307247",
"captcha": "202486"
}
返回数据
名称 | 父级 | 类型 | 必选 | 中文名 | 说明 |
---|---|---|---|---|---|
status | Number | 是 | 请求执行状态 | 成功 200 | |
message | String | 否 | 消息 | 异常信息 | |
success | Boolean | 是 | 是否请求成功 | ||
data | Object | 是 | 返回数据 | ||
existUser | data | Boolean | 是 | 是否存在用户 | |
userId | data | Long | 是 | 用户 ID | |
accessToken | data | String | 是 | token | |
expiresIn | data | Long | 是 | 失效时间(秒) | |
refreshToken | data | String | 是 | refreshToken | |
tokenType | data | String | 是 | bearer |
{
"code": 200,
"success": <strong>true</strong>,
"errorCode": <strong>null</strong>,
"msg": "执行成功~~",
"data": {
"existUser": <strong>true</strong>,
"accessToken": "7e7a337e-a0ee-479b-a74c-d7812a8332f0",
"tokenType": "bearer",
"expiresIn": 43200,
"refreshToken": "642dbcec-1afe-4c02-9d79-487bd9499b19",
"userId": 2989103744245760
}
}
5.2、调用执行逻辑
5.2.1、自动创建用户场景
1、wx.login()调取 code
2、通过【5.1.1】接口把 code 发送给后台 createIfNotExist 传 true,后台通过 code 拿到微信服务接口的 openId,并自动登录绑定用户,不存在则默认创建用户并绑定
3、前端保存后端返回的 accessToken,后续调用后台服务使用
5.2.2、不自动创建用户场景
1、wx.login()调取 code 2、通过后台接口把 code 发送给后台,后台通过 code 拿到微信服务接口的 openId,并登录绑定用户,若不存在绑定用户,接口返回 existUser=false 3、根据 existUser=false 知道无绑定用户,提示用户绑定手机号
4、用户输入手机号并发送验证码【5.1.2】接口 5、调用【5.1.3】接口,后台根据验证码验证手机号通过后,搜索手机号对应的用户,不存在则创建新用户,
6、后台重新通过 code 去获取 openId,并与上一步检索的用户进行绑定,并自动登录返回
7、前端保存后端返回的 accessToken,后续调用后台服务使用