diff --git a/docs/uniCloud/uni-id-pages.md b/docs/uniCloud/uni-id-pages.md index 8fad71c20d6c29321f2f1f4f688ba81db193a887..8c36332200aa27e0fa1b5ddc77c01e5bb9d59758 100644 --- a/docs/uniCloud/uni-id-pages.md +++ b/docs/uniCloud/uni-id-pages.md @@ -250,9 +250,7 @@ uni.navigateTo({ # 云对象(uni-id-co) -uni-id-co是uni-id-pages的核心云对象,包含了诸多用户相关的接口。作为uni-id体系的一部分,uni-id-co也使用uni-id的配置文件(`cloudfunctions/common/uni-config-center/uni-id/config.json`)。详细API列表请参考下方说明 - -## uni-id-co的API列表@co-api +uni-id-co是uni-id-pages的核心云对象,包含了诸多用户相关的接口。作为uni-id体系的一部分,uni-id-co也使用uni-id的配置文件(`cloudfunctions/common/uni-config-center/uni-id/config.json`)。 前端调用云对象`uni-id-co`内的方法前应先获取云对象的引用,代码如下 @@ -260,7 +258,7 @@ uni-id-co是uni-id-pages的核心云对象,包含了诸多用户相关的接 const uniIdCo = uniCloud.importObject('uni-id-co') ``` -### 目录说明 +## 目录说明 ```text ├─common // 公用逻辑 @@ -274,7 +272,7 @@ const uniIdCo = uniCloud.importObject('uni-id-co') └─module // 分模块存放的云对象方法 ``` -### 公共响应参数@co-public-response +## 公共响应参数@co-public-response `uni-id-co`所有api返回值均满足[uniCloud响应体规范](uniCloud/cf-functions?id=resformat) @@ -296,6 +294,44 @@ const uniIdCo = uniCloud.importObject('uni-id-co') - 需要校验token的接口在token即将过期时也会返回newToken,token即将过期的阈值由开发者自行配置 +## API列表 + +|API |描述 | +|-- |-- | +|uniIdCo.registerAdmin() |注册管理员 [详情](#register-admin) | +|uniIdCo.addUser() |新增用户 [详情](#add-user) | +|uniIdCo.authorizeAppLogin() |授权用户登录应用 [详情](#authorize-app-login) | +|uniIdCo.removeAuthorizedApp() |移除用户登录授权 [详情](#remove-authorized-app) | +|uniIdCo.setAuthorizedApp() |设置用户允许登录的应用列表 [详情](#set-authorized-app) | +|uniIdCo.registerUser() |注册普通用户 [详情](#register-user) | +|uniIdCo.login() |用户名密码登录 [详情](#login) | +|uniIdCo.loginBySms() |短信验证码登录 [详情](#login-by-sms) | +|uniIdCo.loginByUniverify() |App端一键登录 [详情](#login-by-univerify) | +|uniIdCo.loginByWeixin() |微信登录 [详情](#login-by-weixin) | +|uniIdCo.loginByAlipay() |支付宝登录 [详情](#login-by-alipay) | +|uniIdCo.loginByQQ() |QQ登录 [详情](#login-by-qq) | +|uniIdCo.loginByApple() |苹果登录 [详情](#login-by-apple) | +|uniIdCo.logout() |用户退出登录 [详情](#logout) | +|uniIdCo.bindMobileBySms() |通过短信验证码绑定手机号 [详情](#bind-mobile-by-sms) | +|uniIdCo.bindMobileByUniverify()|通过一键登录绑定手机号 [详情](#bind-mobile-by-univerify) | +|uniIdCo.bindMobileByMpWeixin() |通过微信绑定手机号 [详情](#bind-mobile-by-mp-weixin) | +|uniIdCo.bindWeixin() |绑定微信 [详情](#bind-weixin) | +|uniIdCo.bindQQ() |绑定QQ [详情](#bind-qq) | +|uniIdCo.bindAlipay() |绑定支付宝账号 [详情](#bind-alipay) | +|uniIdCo.bindApple() |绑定苹果账号 [详情](#bind-apple) | +|uniIdCo.updatePwd() |更新密码 [详情](#update-pwd) | +|uniIdCo.resetPwdBySms() |通过短信验证码重置密码 [详情](#reset-pwd-by-sms) | +|uniIdCo.closeAccount() |注销账户 [详情](#close-account) | +|uniIdCo.getAccountInfo() |获取账户账户简略信息 [详情](#get-account-info) | +|uniIdCo.createCaptcha() |创建图形验证码 [详情](#create-captcha) | +|uniIdCo.refreshCaptcha() |刷新图形验证码 [详情](#refresh-captcha) | +|uniIdCo.sendSmsCode() |发送短信验证码 [详情](#send-sms-code) | +|uniIdCo.refreshToken() |刷新token [详情](#refresh-token) | +|uniIdCo.acceptInvite() |接受邀请 [详情](#accept-invite) | +|uniIdCo.getInvitedUser() |获取受邀用户 [详情](#get-invited-user) | +|uniIdCo.setPushCid() |更新device表的push_clien_id [详情](#set-push-cid) | +|uniIdCo.getSupportedLoginType()|获取支持的登录方式 [详情](#get-supported-login-type) | + ### 注册登录和登出@register-login-logout #### 注册超级管理员@register-admin @@ -1316,646 +1352,6 @@ await uniIdCo.setAuthorizedApp({ - 此接口为管理端接口 - 仅在用户token即将过期时返回新newToken -## uni-id-common公共模块的API列表@api - -自`uni-id 4.0.0`起uni-id公共模块内的大部分接口实现移至uni-id-co内,公共模块内仅保留token相关接口 - -一般开发者无需了解uni-id-common公共模块的API,直接使用[uni-id-pages]()即可(**需要补充链接**)。 - -如果想了解uni-id-common公共模块内部实现,可以阅读本章节。 - -### 基础功能@base - -#### 创建uni-id实例@create-instance - -用法:`uniID.createInstance(Object CreateInstanceParams);` - -CreateInstanceParams内可以传入云函数context,也可以传入clientInfo参数,作用和context类似。方便在云对象内获取clientInfo后直接传入,[什么是云对象?](uniCloud/cloud-obj.md)。 - -```js -// 云函数代码,传入context -const uniID = require('uni-id-common') -exports.main = async function(event,context) { - context.APPID = '__UNI__xxxxxxx' // 替换为当前客户端的APPID,通过客户端callFunction请求的场景可以使用context.APPID获取 - context.PLATFORM = 'h5' // 替换为当前客户端的平台类型,通过客户端callFunction请求的场景可以使用context.PLATFORM获取 - context.LOCALE = 'zh-Hans' // 替换为当前客户端的语言代码,通过客户端callFunction请求的场景可以使用context.LOCALE获取 - const uniIDIns = uniID.createInstance({ // 创建uni-id实例 - context: context, - // config: {} // 完整uni-id配置信息,使用config.json进行配置时无需传此参数 - }) - payload = await uniIDIns.checkToken(event.uniIdToken) // 后续使用uniIDIns调用相关接口 - if (payload.code) { - return payload - } - const res = await uniIDIns.updateUser({ - uid: payload.uid, - nickname: 'user nickname' - }) - return res -} - -// 云对象代码传入clientInfo -const uniID = require('uni-id-common') -module.exports = { - _before() { - const clientInfo = this.getClientInfo() - this.uniID = uniID.createInstance({ // 创建uni-id实例,其上方法同uniID - clientInfo - }) - }, - login() { - // ... - // this.uniID.login() - } -} -``` - -**为什么需要自行创建uni-id实例** - -默认情况下uni-id-common某些接口会自动从全局context内获取客户端的PLATFORM(平台,如:app、h5、mp-weixin)等信息。 - -在单实例多并发的场景下可能无法正确获取(全局对象会被后面的请求覆盖,可能会导致前面一次请求使用了后面一次请求的PLATFORM信息)。因此推荐在开启云函数单实例多并发后,自行为uni-id传入context。 - -此外云函数url化时无法获取客户端信息,也需要使用这种方式将客户端信息传入uni-id。 - -#### token校验@checktoken - -一个校验客户端发起请求(uniCloud.callFunction)自带的uniIdToken,获得用户的uid、token、token的过期时间、角色、权限、用户信息(uni-id-users全部字段)的API。 - -这是非常高频且重要的API通常用于换取操作当前云函数的用户Id。 - -##### 思考 - -如果你并没有服务端开发经验,可能会想:为什么需要通过token去换取用户Id,而不是让客户端直接传递用户Id更方便? -这里就涉及到安全问题,有一句话叫做:“前端传递的参数都是不可信任的”。比如:你去银行取款,柜台会要求出示你的身份证来证明你是谁,而不是你直接告诉银行柜台你是谁就管用。否则这是一个极大的安全漏洞。 -综上所述:所有服务端操作涉及账户信息相关内容,都需要使用token来获得,而不是使用前端传递的参数。 - -用法:`uniID.checkToken(String token, Object checkTokenOptions)` - -**参数说明** - -| 字段 | 类型 | 必填 | 说明 | -| --- | --- | --- | --- | -| token | String | 是 |客户端callFunction带上的token | -| options | object | 否 |checkToken方法的选项 | -|  |- autoRefresh| boolean | 否 |是否需要自动判断刷新token,默认true | - -**说明** - -- 角色内包含admin时返回的permission是一个空数组,因此判断一个用户是否有权限时应注意admin角色额外进行判断 - -请务必阅读一下此文档:[关于缓存角色权限的说明](uniCloud/uni-id.md?id=cache-permission-in-token) - -**响应参数** - -| 字段 | 类型 | 说明 | -| --- | --- | --- | -| errCode | Number|String|错误码,0表示成功 | -| message | String |详细信息 | -| uid | String |用户Id,校验成功之后会返回 | -| token | String |用户token快要过期时,新生成的token,只有在config内配置了`tokenExpiresThreshold`的值时才会有此行为 | -| tokenExpired | TimeStamp |新token的过期时间,单位毫秒 | -| role | Array |- | -| permission | Array |用户权限列表。 | - -uni-id使用jwt生成token,jwt所生成的token包含三部分,其中存储的信息为明文信息,uni-id只根据tokenSecret来校验客户端token是否合法。 - - -角色权限将被缓存在token中,此举能减少或消除checkToken的查库次数(有效节省费用、减少响应时间) - -**注意:** - -- 客户端会自动查找storage内的token在callFunction时插入 -- HBuilderX 2.9.5+ 客户端允许开发者自行在callFunction时传入uniIdToken,此时不再从storage获取token -- HBuilderX 2.8.0版本起token存储在storage内推荐使用使用蛇形`uni_id_token`,会在一段时间内兼容驼峰形式`uniIdToken` - -#### 主动刷新token@refresh-token - -> 新增于uni-id 3.3.14 - -用法:`uniID.refreshToken(Object RefreshTokenParams);` - -**参数说明** - -| 字段| 类型 | 必填| 说明 | -| --- | --- | --- | --- | -| token | String| 是 |用户token| - -**示例** - -```js -const { - token, - tokenExpired -} = await uniID.refreshToken({ - token: 'xxx' -}) -``` - -**注意** - -- 刷新token时会自动更新token内uid对应的角色权限 - -#### 生成token@createtoken - -用法:`uniID.createToken(Object CreateTokenParams)` - -**参数说明** - -| 字段 | 类型 | 必填 | 说明 | -| --- | --- | --- | --- | -| uid | String| 是 |用户Id | -| role | Array | 否 |指定缓存在token内的角色| -| permission| Array | 否 |指定缓存在角色内的权限 | - -**响应参数** - -| 字段 | 类型 | 必填| 说明 | -| --- | --- | --- | --- | -| token | String| 是 |生成的token | -| tokenExpired| Number| 是 |token过期时间对应的时间戳| - -**说明** - -- 创建token时如果未传角色权限会自动获取uid对应的角色权限 - -## uniIdRouter自动路由@uni-id-router - -> 新增于 HBuilderX 3.5.0 - -开发者可以在项目的`pages.json`内配置需要登录的页面,登录页面路径等信息,uniCloud会自动在需要登录且客户端登录状态过期或未登录时跳转到登录页面。 - -结合以下代码及注释了解如何使用`uniIDRouter` - -```json -{ - "pages": [ - { - "path": "pages/index/index", - "style": { - "navigationBarTitleText": "uni-app" - }, - "needLogin": false // 当前页面是否需要登录才可以访问,此配置优先级高于uniIDRouter下的needLogin - }, { - "path": "pages/list/list", - "style": { - "navigationBarTitleText": "uni-app" - }, - "needLogin": false - }, { - "path": "pages/detail/detail", - "style": { - "navigationBarTitleText": "uni-app" - } - } - ], - "globalStyle": { - "navigationBarTextStyle": "black", - "navigationBarTitleText": "uni-app", - "navigationBarBackgroundColor": "#F8F8F8", - "backgroundColor": "#F8F8F8" - }, - "uniIDRouter": { - "loginPage": "pages/index/index", // 登录页面路径 - "needLogin": [ - "pages/detail/.*" // 需要登录才可访问的页面列表,可以使用正则语法 - ], - "resToLogin": true // 自动解析云对象及clientDB的错误码,如果是客户端token不正确或token过期则自动跳转配置的登录页面,配置为false则关闭此行为,默认true - } -} - -``` - -与此功能对应的有两个uniCloud客户端api,`uniCloud.onNeedLogin()`和`uniCloud.offNeedLogin()`,开发者在监听onNeedLogin事件后,框架就不再自动跳转到登录页面,而是由开发者在onNeedLogin事件内自行处理。详情参考:[uniCloud.onNeedLogin](uniCloud/client-sdk.md?id=on-need-login) - -**注意** - -- pages.json内有`uniIDRouter`节点上述逻辑才会生效,自HBuilderX 3.5.0起创建空项目模板会自动配置空的`uniIDRouter`节点 - -## 错误码@errcode - -|错误码 |错误信息 |说明 | -|---- |---- |---- | -|0(数字) |成功 |- | -|uni-id-token-expired |登录状态失效,token已过期 |- | -|uni-id-check-token-failed |token校验未通过 |- | -|uni-id-account-exists |账户已存在 |- | -|uni-id-account-not-exists |账户不存在 |- | -|uni-id-account-conflict |用户账号冲突 |可能会由开发者手动更新数据库导致,正常情况下不应出现 | -|uni-id-account-banned |此账号已封禁 |- | -|uni-id-account-auditing |此账号正在审核中 |- | -|uni-id-account-audit-failed |此账号审核失败 |- | -|uni-id-account-closed |此账号已注销 |- | -|uni-id-captcha-required |请输入图形验证码 |- | -|uni-id-password-error |用户名或密码错误 |- | -|uni-id-invalid-username |用户名不合法 |- | -|uni-id-invalid-password |密码不合法 |- | -|uni-id-invalid-mobile |手机号码不合法 |- | -|uni-id-invalid-email |邮箱不合法 |- | -|uni-id-invalid-nickname |昵称不合法 |- | -|uni-id-invalid-param |参数错误 |- | -|uni-id-param-required |缺少参数 |- | -|uni-id-get-third-party-account-failed |获取第三方账号失败 |- | -|uni-id-get-third-party-user-info-failed|获取第三方用户信息失败 |- | -|uni-id-mobile-verify-code-error |手机验证码错误或已过期 |- | -|uni-id-email-verify-code-error |邮箱验证码错误或已过期 |- | -|uni-id-admin-exists |超级管理员已存在 |- | -|uni-id-permission-error |权限错误 |- | -|uni-id-system-error |系统错误 |- | -|uni-id-set-invite-code-failed |设置邀请码失败 |- | -|uni-id-invalid-invite-code |邀请码不可用 |- | -|uni-id-change-inviter-forbidden |禁止修改邀请人 |- | -|uni-id-bind-conflict |此账号(微信、QQ、手机号等)已被绑定 |- | - -## 多个应用复用相同uni-id-user表 - -有些系统由多个子应用组成,且没有各自独立服务空间,而是需要共享一个服务空间。此时就涉及一个问题,多个应用注册的账户都在uni-id-user表中,如何有效隔离。 - -比如一个打车软件,有乘客端、司机端、管理端,都要注册账户。它们也都有自己的DCloud appID(manifest.json里第一个配置) - -uni-id-user表中有一个数组型字段`dcloud_appid`,可以存贮这个用户有权登录哪个应用。 - -比如乘客端的appid是`__uni_111111`,司机端appid是`__uni_222222`,那么2个appid都存入`dcloud_appid`,即表示这个用户有权登录这2个应用。 - -### 隔离不同应用的用户@isolate-user - -uni-id 3.3.0版本起用户注册时会自动在用户表的记录内标记为注册应用对应的用户,如果没有单独授权登录其他应用的话则只能登录这个应用。即在乘客端应用注册的,默认只能在乘客端应用登录。 - -如何授权登录其他应用请参考:[授权、禁止用户在特定客户端应用登录](uniCloud/uni-id?id=authorize-app) - -需要注意的是客户端APPID信息是由端上传上来的,并非完全可信,尽量在入口处进行校验。例: - -```js -exports.main = async function(event, context){ - if(context.APPID !== '__UNI__xxx1') { - throw new Error('应用ID非法') - } -} -``` - -**DCloud Appid是一个很重要的配置,如无必要请勿随意更换。** - -> 不同端用户数据通过用户表的dcloud_appid字段隔离,同一个手机号、微信号也可以同时注册管理端和用户端,绑定账号同理。 - -**注意** - -- uni-id会自动在用户表每条用户记录插入`dcloud_appid`字段(此字段是一个数组,标识此用户可以在哪些端登录)。 -- 为兼容旧版本产生的旧数据,针对没有dcloud_appid字段的用户,允许登录任意端。 -- 如果用户数据库记录中`dcloud_appid`字段是一个空数组,表示当前用户不能在任何客户端登录 -- 已有dcloud_appid的用户,如果使用相同的用户标识(用户名、邮箱、手机、微信等)+ 不同的DCloud Appid登录会被判定为不同的用户,如果此时数据库没有对应的记录,会报用户不存在的错误 - -### 隔离不同应用的配置@isolate-config - -> `uni-id 3.3.0`及以上版本 - -uni-id的config.json支持配置为数组,每项都是一个完整的配置,对不同的配置使用`dcloudAppid`字段进行区分(**此字段与项目内的manifest.json里面的DCloud AppId一致**),uni-id会自动根据客户端的appid来判断该使用哪套配置。如果使用云函数url化请参考:[云函数Url化时使用](uniCloud/uni-id?id=url) - -需要注意的是客户端APPID信息是由端上传上来的,并非完全可信,尽量在入口处进行校验。例: - -```js -exports.main = async function(event, context){ - if(context.APPID !== '__UNI__xxx1') { - throw new Error('应用ID非法') - } -} -``` - -**示例** - -> 数组每一项都是一个完整的配置文件,全部选项请参考:[uni-id 配置](uniCloud/uni-id?id=config) - -**注意:如果允许同一账号在不同端使用相同的账号+密码登录需要将不同端的passwordSecret设置成一样的** - -```js -[{ - "dcloudAppid": "__UNI__xxxx1", // 务必替换为对应项目manifest.json内的DCloud Appid - "isDefaultConfig": true, // 默认配置标记,未匹配到dcloudAppid的情况下使用默认配置 - "passwordSecret": "passwordSecret-demo", - "tokenSecret": "tokenSecret-demo", - "tokenExpiresIn": 7200, - "tokenExpiresThreshold": 600 -}, { - "dcloudAppid": "__UNI__xxxx2", // 务必替换为对应项目manifest.json内的DCloud Appid - "passwordSecret": "passwordSecret-demo", - "tokenSecret": "tokenSecret-demo", - "tokenExpiresIn": 7200, - "tokenExpiresThreshold": 600 -}] -``` - - -## 其他功能 - -### 裂变@fission - -在`config.json`内配置了`autoSetInviteCode: true`则在用户注册时会自动给设置不重复的6位邀请码 - -在`config.json`内配置了`forceInviteCode: true`则只有使用邀请码才可以注册。 - -`uni-id-co`在会产生注册行为的接口均添加了inviteCode参数,用于传递邀请码使注册用户接受邀请 - -### 修改passwordSecret@modifysecret - -**注意:通常情况下设定好passwordSecret之后不需要再进行修改,使用此功能时请务必小心谨慎** - -**说明** - -在config.json内修改passwordSecret会导致历史用户无法通过密码登录。但是某些情况下有些应用有修改passwordSecret的需求,例如刚开始使用uni-id时没有自定义passwordSecret,后续需要修改,此时可以使用uni-id 2.0.1版本新增的修改passwordSecret功能。(注意:2.0.1版本验证码表名调整为了`opendb-verify-codes`) - -**如何使用** - -下面以将passwordSecret从`passwordSecret-demo`修改为`qwertyasdfgh`为例介绍如何使用 - -```json -// 旧config.json -{ - "passwordSecret": "passwordSecret-demo" -} - -// 新config.json -{ - "passwordSecret": [{ - "version": 1, - "value": "passwordSecret-demo" - },{ - "version": 2, - "value": "qwertyasdfgh" - }] -} - -``` - -如果在上面基础上再修改passwordSecret为`1q2w3e4r5t`,config.json调整如下 - -> !!!注意只有在数据库内完全没有使用某个版本(`password_secret_version`字段表示了用户密钥版本)密钥的用户才可以将此密钥从config.json内去除。没有`password_secret_version`的用户使用的是最旧版本的passwordSecret,如果存在这样的用户对应的passwordSecret也不可去除。 - -```json -// 新config.json, -{ - "passwordSecret": [{ - "version": 1, - "value": "passwordSecret-demo" - },{ - "version": 2, - "value": "qwertyasdfgh" - },{ - "version": 3, - "value": "1q2w3e4r5t" - }] -} -``` - -**原理** - -uni-id-users表内存储的password字段为使用hmac-sha1生成的hash值,此值不可逆向推出用户真实密码。所以直接修改passwordSecret会导致老用户无法使用密码登录。 - -上述修改通过密钥版本号区分新旧密钥,用户登录时如果密钥版本小于当前最新版本,会为用户更新数据库内存储的password字段,并记录当前使用的密钥版本。 - -用户对应的数据库记录内没有密钥版本的话会使用最低版本密钥进行密码校验,校验通过后为用户更新为最新版密钥对应的password并记录版本号。 - -由于是不可逆加密,理论上passwordSecret泄露不会造成用户的真实密码被泄露,自定义passwordSecret只是进一步加强安全性。 - -### 缓存角色权限@cache-permission-in-token - -使用`uni-id-common`时,token内会缓存用户的角色权限。 - -为什么要缓存角色权限?要知道云数据库是按照读写次数来收取费用的,并且读写数据库会拖慢接口响应速度。 - -详细checkToken流程如下: - -![](https://bjetxgzv.cdn.bspapp.com/VKCEYUGU-dc-site/ed45d350-5a4d-11eb-b997-9918a5dda011.jpg) - -可以看出,旧版token(removePermissionAndRoleFromToken为true时生成的)在checkToken时如需返回权限需要进行两次数据库查询。新版token不需要查库即可返回权限信息。 - -**注意** - -- 由于角色权限缓存在token内,可能会存在权限已经更新但是用户token未过期之前依然是旧版角色权限的情况。可以调短一些token过期时间来减少这种情况的影响。 -- admin角色token内不包含permission,如需自行判断用户是否有某个权限,要注意admin角色需要额外判断一下,写法如下 - ```js - const { - role, - permission - } = await uniID.checkToken(event.uniIdToken) - if(role.includes('admin') || permission.includes('your permission id')) { - // 当前角色拥有'your permission id'对应的权限 - } - ``` - -### 自定义token内容@custom-token - -> uni-id 3.0.7及以上版本,且需要使用[uni-config-center](https://ext.dcloud.net.cn/plugin?id=4425) - -自`uni-id 3.0.0`起,支持在token内缓存用户的角色权限。但是某些情况下开发者可能还希望缓存一些别的东西,以便在客户端能方便的访问(**注意:不可缓存机密信息到token内**)。 - -**用法** - -在`uni-config-center`模块内的uni-id插件内创建`custom-token.js`内容如下: - -```js -module.exports = async (tokenObj) => { - // tokenObj为原始token信息结构如下 - // { - // uid: 'abc', // 用户id - // role: [], // 用户角色列表 - // permission: [] // 用户权限列表,admin角色的用户权限列表为空数组 - // } - - tokenObj.customField = 'hello custom token' // 自定义token字段 - return tokenObj // 注意务必返回修改后的token对象 -} -``` - -uni-id会自动加载custom-token.js进行处理,在所有生成token的操作(包括:登录、注册、token过期自动刷新、开发者自行调用createToken)执行时自动获取新token信息,并生成token。 - -**注意** - -- 使用custom-token时自行调用createToken接口会变为异步操作,需使用`await uniID.createToken(...)` -- 不要删除原始token内的字段 - -### 自定义国际化语言@custom-i8n - -> 新增于uni-id 3.3.10,此功能依赖于[uni-config-center] - -完整词句列表参考:[uni-id中文语言包](https://gitee.com/dcloud/uni-id/blob/master/src/lang/zh-Hans.js) - -**用法** - -在`cloudfunctions/common/uni-config-center/uni-id/lang/`目录下创建`index.js`,内容示例如下: - -```js -module.exports = { - 'zh-hant': { // 语言代码 - 'alipay': '支付寶' - } -} -``` - -uni-id会自动进行语言匹配,无需额外配置 - - -### 云函数Url化时使用@url - -云函数url化时uni-id无法自行获取客户端相关信息,需要开发者自行创建uniID实例并传入相关信息,以下为一个简单示例 - -**注意:实际业务中务必验证一下前端传来的数据的合法性,APPID、PLATFORM等均来自前端** - -```js -// 客户端代码示例 -uni.request({ - url: 'https://xxx.xxx/xxx?appid=your_appid&platform=your_platform&deviceId=your_deviceId' -}) - -// 云函数代码示例 -const uniID = require('uni-id') -exports.main = async function(event, context) { - const { - appid, - platform - } = event.queryStringParameters // 不同类型的请求获取参数的方式略有差异,具体如何取参数请参考:https://uniapp.dcloud.net.cn/uniCloud/http - context.APPID = appid - context.PLATFORM = platform - const uniIDIns = uniID.createInstance({ - context - }) - // uniIDIns.checkToken() 使用uniIDIns来调用uni-id相关接口 -} -``` - - -## uni-id公共模块迁移指南@migration - -### 自1.x.x版本升级到2.x.x@m1to2 - -自2.0.0版本起uni-id调整了验证码表名(这个调整导致了与旧版不兼容),如果要使用2.0.0以上版本需要在数据库中创建opendb-verify-code表(建议直接选择opendb内uni-id下的opendb-verify-code表,会自动创建索引以及表结构) - -### 自2.x.x版本升级到3.x.x@m2to3 - -3.0.0版本起uni-id默认将缓存用户角色权限到token内,关于缓存角色权限的说明请参考:[缓存角色权限](uniCloud/uni-id?id=cache-permission-in-token)。从2.x.x版本升级到3.x.x版本需要根据自己需求分别处理。 - -- 如果不希望缓存角色权限到token内,需要在config.json内配置`"removePermissionAndRoleFromToken": true`。 -- 如果希望升级为缓存角色权限到token内的方案,可以按照以下步骤迁移 - + 各登录接口的needPermission参数不再生效,checkToken校验新token时总是返回角色权限 - + 所有注册用户行为均支持传入角色(role)字段,指定创建用户的角色(需要使用3.0.2及以上版本,此前只有uniID.register接口支持)。由于需要初始生成的token内带有角色权限,所以推荐在注册时就给用户设置好角色。 - -##### uniCloud admin升级uni-id@m2to3-uni-admin - -uniCloud admin可以平滑升级到uni-id 3.0.0。如果要缓存角色权限到token内(uni-id 3.0.0的默认行为),那还有几点可以优化。详细调整如下 - -1. `uniCloud-aliyun\cloudfunctions\uni-admin\middleware\auth.js` - - auth中间件内可以调整为checkToken时不再获取用户信息,这样auth中间件就无需进行数据库查询,可以加速接口响应 - -2. `uniCloud-aliyun\cloudfunctions\uni-admin\controller\app.js` - - 受第一步影响app/init内无法获取用户信息,可以额外调用uniID的getUserInfo获取 - -可以参考此次提交进行调整:[uniCloud admin](https://github.com/dcloudio/uniCloud-admin/commit/8359d699aacb8f7d074fce9aa82a36474cb6e7df) - -##### 使用uni-config-center@uni-config-center - -> uni-id 3.0.7及以上版本 - -从插件市场导入支持uni_modules的uni-id,会自动安装依赖的uni-config-center到uni_modules内。如果此前并没有使用uni-config-center可以直接将uni-id的config.json移至`uni-config-center/uni-id/config.json`即可(可以参照插件市场的uni-id示例项目) - -- uni-id会优先使用uni-config-center内添加的配置 -- 如果批量上传后报“请在公用模块uni-id的config.json或init方法中内添加配置项”,请重新上传一次`uni-id` - -**uni-id配置优先级** - -1. `uniID.init`、`uniID.createInstance`传入的配置(此配置不会对clientDB依赖的uni-id生效,不推荐使用) -2. uni-config-center内配置的`uni-id/config.json`(推荐使用的配置方式) -3. uni-id插件下配置的config.json(已不推荐使用的配置方式) - -以上三个配置不会进行合并,优先级高的先生效 - -##### 忽略用户名邮箱大小写@case-sensitive - -> uni-id 3.1.0及以上版本 - -uni-id 3.1.0版本主要有以下两个调整 - -1. 自此版本起会对所有接口中的用户名、邮箱、密码进行前后去空格。 - -2. 此版本之前uni-id并未忽略用户名及邮箱的大小写。这样导致了一些问题,比如用户在手机上登录不小心就会使用首字母大写的用户名或邮箱,这样就会登录失败,影响用户体验。很多应用/网站的登录都是忽略大小写的,为此uni-id在3.1.0版本起调整为默认忽略用户名、邮箱的大小写。实现方式为将用户名、邮箱均存储为小写,用户输入用户名邮箱时也转化为小写进行匹配 - -**注意** - -- 此调整兼容旧版本,以登录接口为例,优先匹配用户输入用户名对应的账号,如果不存在则匹配全小写用户名对应的账号(uni-id内部进行处理实际不会增加数据库读写次数) -- 新注册用户会将用户名/邮箱存储为全小写格式,老用户可能还存在包含大写字母的邮箱及用户名 - -##### 补齐用户dcloud_appid字段@makeup-dcloud-appid - -此调整详情见:[隔离不同端用户](uniCloud/uni-id.md?id=isolate-user) - -> uni-id3.3.0以下版本升级到3.3.0及以上版本时,需要参照本章节补齐用户数据 - -uni-id在3.3.0提供了根据客户端appid(项目manifest.json内配置的DCloud Appid)隔离不同用户的功能,旧版本的uni-id在注册用户时并未将当前客户端的appid存储在用户的记录内,更新到新版后这些没有dcloud_appid字段的用户和之前一样可以登录所有端。开发者使用云函数本地运行可以自行对用户数据进行修补,为用户创建dcloud_appid字段 - -**更新后用户将只允许登录与自己数据库记录内匹配的端** - -云函数示例代码如下: - -**注意:如果要更新的记录很多可能会超时失败,此时无需重试等待数据库自行完成更新即可** - -**如果仅有一端,将所有用户的数据更新为同一个dcloud_appid即可,例:** - -```js -exports.main = async function() { - const db = uniCloud.database() - const userCollection = db.collection('uni-id-users') - const res = await userCollection.where({ - dcloud_appid: db.command.exists(false) // 更新所有不存在dcloud_appid字段的用户 - }).update({ - dcloud_appid: ['你项目内manifest.json里面的DCloud Appid,__UNI_xxxx形式'] // 注意这里是个数组,务必正确填写 - }) - return res -} -``` - -**如果之前就有区分不同端的用户,可以将自己区分用户的条件加上再进行更新,例:** - -```js -// 更新教师端用户的云函数 -exports.main = async function() { - const db = uniCloud.database() - const userCollection = db.collection('uni-id-users') - const res = await userCollection.where({ - user_type: 'teacher', // 教师端用户 - dcloud_appid: db.command.exists(false) - }).update({ - dcloud_appid: ['教师端项目内manifest.json里面的DCloud Appid,__UNI_xxxx形式'] // 注意这里是个数组,务必正确填写 - }) - return res -} - -// 更新学生端用户的云函数 -exports.main = async function() { - const db = uniCloud.database() - const userCollection = db.collection('uni-id-users') - const res = await userCollection.where({ - user_type: 'student', // 学生端用户 - dcloud_appid: db.command.exists(false) - }).update({ - dcloud_appid: ['学生端项目内manifest.json里面的DCloud Appid,__UNI_xxxx形式'] // 注意这里是个数组,务必正确填写 - }) - return res -} -``` - -**如果允许用户在多个端登录需要将多端的DCloud Appid都传进来,例:** - -```js -exports.main = async function() { - const db = uniCloud.database() - const userCollection = db.collection('uni-id-users') - const res = await userCollection.where({ - dcloud_appid: db.command.exists(false) // 更新所有不存在dcloud_appid字段的用户 - }).update({ - dcloud_appid: ['DCloud Appid1','DCloud Appid1'] // 注意这里是个数组,务必正确填写 - }) - return res -} -``` # 登录服务开通与配置 服务端`uni-id`的密钥信息统一在`uni-config-center`中配置,路径:`uni_modules/uni-config-center/uniCloud/cloudfunctions/common/uni-config-center/uni-id/config.json`