English
uni-id-pages
, part of the uni-id
system.
Based on uni-id-common
, it provides a batch of ready-made, open-source, front-end pages and cloud objects related to login and account management.
It is a uni_modules of a cloud-integrated page group, including front-end pages and back-end cloud objects (uni-id-co).
Developers introduce uni-id-pages
into the project, and account management functions do not need to be developed by themselves. Due to the openness of the source code and the clear hierarchical structure, it is also easy to adjust if there are secondary development needs.
Download address: https://ext.dcloud.net.cn/plugin?name=uni-id-pages
Features of uni-id-pages
include:
├─uni_modules 存放[uni_module](/uni_modules)规范的插件。
│ ├─其他module
│ └─uni-id-pages
│ ├─uniCloud
│ │ └─cloudfunctions 云函数目录
│ │ └─uni-id-co 集成调用uni-id方法的云对象
│ │ ├─common 公用逻辑
│ │ ├─config 配置
│ │ │ └─permission.js 调用接口所需的权限配置
│ │ ├─lang 国际化目录
│ │ ├─lib 基础功能,不建议修改此目录下文件
│ │ │ ├─third-party 三方平台接口
│ │ │ └─utils 基础功能
│ │ ├─middleware 中间件
│ │ └─module 分模块存放的云对象方法
│ ├─common
│ │ ├─login-page.scss 登录页面公共样式
│ │ ├─login-page.mixin.js 登录页面公共mixin文件
│ │ └─loginSuccess.js 登录成功后执行的文件
│ ├─components
│ │ ├─cloud-image uniCloud云存储图片解析组件
│ │ │ └─cloud-image.vue
│ │ ├─uni-id-pages-agreements 同意用户服务协议&隐私政策条款组件
│ │ │ └─uni-id-pages-agreements.vue
│ │ ├─uni-id-pages-avatar 用户头像组件
│ │ │ └─uni-id-pages-avatar.vue
│ │ ├─uni-id-pages-bind-mobile 通过微信获取手机号码绑定个人资料
│ │ │ └─uni-id-pages-bind-mobile.vue
│ │ ├─uni-id-pages-email-form 邮箱验证码组件
│ │ │ └─uni-id-pages-email-form.vue
│ │ ├─uni-id-pages-fab-login 悬浮的切换登录方式组件
│ │ │ └─uni-id-pages-fab-login.vue
│ │ ├─uni-id-pages-sms-form 获取短信验证码组件
│ │ │ └─uni-id-pages-sms-form.vue
│ │ └─uni-id-pages-user-profile 获取用户信息组件
│ │ └─uni-id-pages-user-profile.vue
│ ├─pages
│ │ ├─common
│ │ │ └─webview 用于实现应用内浏览或打开《用户协议和隐私协议》URL链接页面
│ │ │ └─webview.vue
│ │ ├─login
│ │ │ ├─login-smscode.vue 短信验证码登录
│ │ │ ├─login-withoutpwd.vue 免密码登录
│ │ │ └─login-withpwd.vue 密码登录
│ │ ├─register
│ │ │ ├─register.vue 通过用户名密码注册账号
│ │ │ ├─register-admin.vue 创建超级管理员
│ │ │ ├─register-by-email.vue 通过邮箱验证码注册账号
│ │ │ └─validator.js 注册账号页的表单验证规则文件
│ │ ├─retrieve
│ │ │ ├─retrieve-by-email.vue 通过邮箱验证码重置密码
│ │ │ └─retrieve.vue 通过手机验证码重置密码
│ │ └─userinfo
│ │ ├─bind-mobile.vue 绑定手机号码
│ │ ├─change_pwd.vue 修改密码
│ │ ├─cropImage.vue 裁剪图片
│ │ ├─deactivate.vue 注销账号
│ │ ├─set-pwd.vue 设置密码
│ │ └─userinfo.js 注册账号页的表单验证规则文件
│ ├─static 静态资源目录
│ ├─changelog.md 更新日志
│ ├─config.js uni-id-pages的配置文件
│ ├─init.js 初始化文件
│ ├─package.json 包管理文件
│ └─readme.md 插件自述文件
**Complete uni-app directory structure [View details](https://uniapp.dcloud.io/frame?id=%e7%9b%ae%e5%bd%95%e7%bb%93%e6%9e %84)
需要在App.vue中初始化uni-id-pages
的init.js
文件
The sample code is as follows:
<script>
import uniIdPageInit from '@/uni_modules/uni-id-pages/init.js';
export default {
onLaunch: async function() {
console.log('App Launch')
await uniIdPageInit()
},
onShow: function() {
console.log('App Show')
},
onHide: function() {
console.log('App Hide')
}
}
</script>
Path: /uni_modules/uni-id-pages/config.js
Field | Type | Description |
---|---|---|
debug | Boolean | Debug mode details |
loginTypes | Array | Login MethodsDetails |
agreements | Array | Privacy Policy details |
appid | Object | Application id for accessing various services (such as WeChat login service)Details |
passwordStrength | Object | Password configuration details |
setPasswordAfterLogin | Boolean/Object | Set password after login details |
Complete example:
export default {
// debug mode
"debug":true,
/*
登录类型 未列举到的或运行环境不支持的,将被自动隐藏。
如果需要在不同平台有不同的配置,直接用条件编译即可
*/
"loginTypes": [
"univerify",
"weixin",
"username",
"apple",
"smsCode"
],
// policy agreement
"agreements": {
"serviceUrl": "https://xxx", //用户服务协议链接
"privacyUrl": "https://xxx", //隐私政策条款链接
// Which scenarios are displayed, 1. Registration (including registration and login, such as: WeChat login, Apple login, SMS verification code login), 2. Login (such as: username and password login)
"scope": ['register', 'login']
},
// The application id that provides access to various services (such as WeChat login service)
"appid":{
"weixin":{
// 微信公众号的appid,来源:登录微信公众号(https://mp.weixin.qq.com)-> 设置与开发 -> 基本配置 -> 公众号开发信息 -> AppID
"h5":"wx111111111111111",
// 微信开放平台的appid,来源:登录微信开放平台(https://open.weixin.qq.com) -> 管理中心 -> 网站应用 -> 选择对应的应用名称,点击查看 -> AppID
"web":"wx22222222222222"
}
},
/**
* 密码强度
* super(超强:密码必须包含大小写字母、数字和特殊符号,长度范围:8-16位之间)
* strong(强: 密密码必须包含字母、数字和特殊符号,长度范围:8-16位之间)
* medium (中:密码必须为字母、数字和特殊符号任意两种的组合,长度范围:8-16位之间)
* weak(弱:密码必须包含字母和数字,长度范围:6-16位之间)
* 为空或false则不验证密码强度
*/
"passwordStrength":"medium",
/**
* 登录后允许用户设置密码(只针对未设置密码得用户)
* 开启此功能将 setPasswordAfterLogin 设置为 true 即可
* "setPasswordAfterLogin": false
*
* 如果允许用户跳过设置密码 将 allowSkip 设置为 true
* "setPasswordAfterLogin": {
* "allowSkip": true
* }
* */
"setPasswordAfterLogin": false
}
In debug mode, starting the application will automatically initiate a network request (calling getSupportedLoginType
of uni-id-co
).
Check: Whether the login method configured on the uni-id-pages client is not configured correctly on the uniCloud server, otherwise an exception will be thrown.
Fields | Description | Platform Differences |
---|---|---|
univerify | One-click login | App 3.0.0+ |
smsCode | SMS verification code login | |
weixin | WeChat login | App, WeChat applet, Web (supported from uni-id-pages version 1.0.8) |
apple | Sign in with Apple Sign in with Apple | iOS13+ support, App 2.4.7+ |
username | Login with username and password |
export default {
"loginTypes": ["username","smsCode"]
}
As shown in the above example configuration, it means to enable: account password login, verification code login.
The same configuration is:
export default {
"loginTypes": ["weixin","username","smsCode"]
}
It means enable: WeChat login, verification code login, account password login.
Platform difference configuration: If you want to have different login methods on different platforms, directly use [conditional compilation](https://uniapp.dcloud.io/platform?id=%e6%9d%a1%e4%bb% b6%e7%bc%96%e8%af%91) is enough. The following configuration means that SMS verification code login
is only enabled on the APP side
export default {
"loginTypes": [
"username","univerify","weixin","apple"
// #ifdef APP-PLUS
,"smsCode"
// #endif
]
}
Note: AppStore rules for iOS: If an app supports three-party social login services (such as: one-key login, WeChat login, etc.), it must also provide users with the option of "Login with Apple Account". That is: if your application does not support three-way login, you can not bring Apple login, if your application supports three-way login, you must also bring Apple login.
The above configuration only opens the front-end login entry. To achieve the function, you need to:
uni-id
module of the server. For details, check: [Login service activation and configuration](#%E7%99%BB%E5%BD%95%E6%9C%8D%E5%8A%A1%E5%BC%80%E9%80%9A%E4 %B8%8E%E9%85%8D%E7%BD%AE)one-click login
, WeChat login
, Apple login
, you need to check the corresponding module in manifest.json
(WeChat login must be configured: WeChat development platform application appID value) , and is available after the package is completed (custom debugging base package and official package are available).Field | Type | Description |
---|---|---|
serviceUrl | String | User service protocol network link |
privacyUrl | String | Privacy Policy Web Link |
scope | Object | Which scenarios does it apply to |
scope description:
Field | Type | Description |
---|---|---|
register | String | Register (including registration and login, such as: WeChat login, Apple login, SMS verification code login) |
login | String | Login (eg: login with username and password) |
一款规范的小程序或App要上架到国内应用商店必须提供《隐私政策和用户使用协议》,参考模版:隐私权政策模板.zip
More compliance issues [see details](https://uniapp.dcloud.io/tutorial/android-store.html#app%E5%9B%A0%E5%90%88%E8%A7%84%E9% 97%AE%E9%A2%98%E6%97%A0%E6%B3%95%E4%B8%8A%E6%9E%B6)
Recommended use: HBuilderX editor, edit the "Privacy Policy and User Agreement" in markdown document format, by right-clicking in the document one-click sharing to front-end web hosting to get the link
Field | Type | Description |
---|---|---|
weixin | Object | |
|- h5 | String | WeChat official account appid Source: WeChat official account-> Settings and Development-> Basic Configuration -> Official Account Development Information -> AppID |
|- web | String | WeChat Open Platform appid Source: WeChat Open Platform -> Management Center -> Website Application -> Select the corresponding application name, click View -> AppID |
Field | Type | Description |
---|---|---|
empty or false | - | do not verify password strength |
super | String | Super strong: the password must contain uppercase and lowercase letters, numbers and special symbols, length range: between 8 and 16 characters |
strong | String | Strong: password must contain letters, numbers and special symbols, length range: between 8-16 characters |
medium | String | Medium: password must be a combination of any two letters, numbers and special symbols, length range: between 8-16 characters |
weak | String | Weak: Password must contain letters and numbers, length range: between 6-16 characters |
If the user has not set a password, he will jump to the password setting page after logging in
This function is not enabled by default, please set setPasswordAfterLogin
to true
to enable it, as follows:
{
setPasswordAfterLogin: true,
// setPasswordAfterLogin: {
// allowSkip: false
// }
}
If you don't need to enforce setting a password, you can set allowSkip
to true
, and users can choose to skip setting a password.
uni-id-pages
includes: account registration, password-free login, avatar replacement, nickname modification, mobile phone number binding, password retrieval, account cancellation and other pages. Plugin address
There is often a need to open the login page in the project. Here is an introduction to the login page; there are two types of login methods:
/uni_modules/uni-id-pages/pages/login/login-withpwd
/uni_modules/uni-id-pages/pages/login/login-withoutpwd
Execute uni.navigateTo
to open the login page, the first item of the loginTypes
value in the configuration will be used as the login method by default.
For example loginTypes
: ["weixin","apple","univerify"]
will use weixin
, ie WeChat login
as the default login method
uni-id-pages
supports specifying the login method by passing the parameter type
. For example: to specify Apple login, use the following code
uni.navigateTo({
"url":"/uni_modules/uni-id-pages/pages/login/login-withoutpwd?type=apple"
})
uniIdRouter can be used together; when the user is not logged in, but visits a page that requires forced login, or the interface prompts that the token is invalid or expired (the response body starts with TOKEN_INVALID) You need to open the login page at all times. You need to define the above two path paths as loginPage
.
uni-id-co is the core cloud object of uni-id-pages, including many user-related interfaces. As part of the uni-id system, uni-id-co also uses the uni-id configuration file (cloudfunctions/common/uni-config-center/uni-id/config.json
). Currently, this cloud object relies on some client information and does not support being called by other cloud functions/cloud objects. Already supports urlization calls, reference: uni-id-co urlization
The front-end should obtain the reference of the cloud object before calling the method in the cloud object uni-id-co
. The code is as follows
const uniIdCo = uniCloud.importObject('uni-id-co')
If there is an error that the lodash.merge
module cannot be found when calling the uni-id-co method, please manually execute npm install
in the uni-id-co cloud object directory. If the client is running, the uniCloud plugin will automatically install the missing dependencies for uni-id-co.
├─common // 公用逻辑
├─config // 配置
│ └─permission.js // 调用接口所需的权限配置
├─lang // 国际化目录
├─lib // 基础功能,不建议修改此目录下文件
│ ├─third-party // 三方平台接口
│ └─utils // 基础功能
├─middleware // 中间件
└─module // 分模块存放的云对象方法
All api return values of uni-id-co
satisfy the uniCloud response body specification
Return value example
{
errCode: 0, // 错误码,详见错误码列表
errMsg: '', // 错误信息,uni-id-co会自动根据客户端语言对错误信息进行国际化
newToken: { // 注册、登录、刷新token等接口会自动返回新token,uniCloud客户端sdk会自动将新token及过期时间存储在storage内(需要HBuilderX 3.4.13及以上版本)
token,
tokenExpired
},
// ... the rest of the parameters
}
Notice
URLization is supported since uni-id-pages@1.0.29
version What is URLization
Call specification:
Content-Type
in the HTTP request header must be application/json
, the request method must be POST
, if the conditions are not met, the uni-id-unsupported-request
error code will be returned{
"clientInfo": {},
"uniIdToken": "",
"params": {}
}
field description
Field | Description |
---|---|
clientInfo | Client information; fields returned by uni.getSystemInfo |
uniIdToken | User Token; Required after user login |
params | API interface parameter field |
如果是在 uni-app 之外的应用中调用 URL 化接口,请确保clientInfo中存在以下字段:
字段 | 说明 |
---|---|
uniPlatform | 应用运行平台,与条件编译平台相同。详见 |
appId | manifest 中应用appid,即DCloud appid。如没有请手动指定一个,需确保唯一性。 |
deviceId | 设备 id;通过uni.getSystemInfo获取 |
Assuming that the URLized domain name PATH has been set in the uniCloud console, take the PATH as /http/uni-id-co
as an example to demonstrate the login example:
uni.request({
url: 'https://{云函数Url化域名}/http/uni-id-co/login',
method: 'POST',
data: {
clientInfo: uni.getSystemInfoSync(),
uniIdToken: '用户Token',
params: {
username:"username",
password:"password"
}
},
header: {
'Content-Type': 'application/json'
},
success: (res) => {
// return value
}
})
Notice
Please do not add the Query parameter, the Query parameter will be ignored after URLization
API | Description |
---|---|
uniIdCo.registerAdmin() | Register Admin Details |
uniIdCo.addUser() | Add User Details |
uniIdCo.authorizeAppLogin() | Authorize users to log in to the app details |
uniIdCo.removeAuthorizedApp() | Remove user login authorization Details |
uniIdCo.setAuthorizedApp() | Set the list of apps that the user is allowed to log in Details |
uniIdCo.registerUser() | Register ordinary user Details |
uniIdCo.registerUserByEmail() | Register ordinary users through email verification code Details |
uniIdCo.login() | Login with username and password Details |
uniIdCo.loginBySms() | SMS verification code login Details |
uniIdCo.loginByUniverify() | App-side one-click login Details |
uniIdCo.loginByWeixin() | WeChat login Details |
uniIdCo.loginByAlipay() | Alipay login Details |
uniIdCo.loginByQQ() | QQ login Details |
uniIdCo.loginByApple() | Apple login Details |
uniIdCo.logout() | User logout details |
uniIdCo.bindMobileBySms() | Bind mobile phone number through SMS verification code Details |
uniIdCo.bindMobileByUniverify() | Bind mobile phone number by one-click login Details |
uniIdCo.bindMobileByMpWeixin() | Bind mobile phone number through WeChat Details |
uniIdCo.bindWeixin() | Bind WeChat Details |
uniIdCo.bindQQ() | Bind QQ Details |
uniIdCo.bindAlipay() | Bind Alipay account Details |
uniIdCo.bindApple() | Bind Apple Account Details |
uniIdCo.updatePwd() | Update password details |
uniIdCo.resetPwdBySms() | Reset password via SMS verification code Details |
uniIdCo.resetPwdByEmail() | Reset password by email verification code Details |
uniIdCo.closeAccount() | Close account Details |
uniIdCo.getAccountInfo() | Get brief account information Details |
uniIdCo.createCaptcha() | Create a graphic captcha Details |
uniIdCo.refreshCaptcha() | Refresh the graphic captcha details |
uniIdCo.sendSmsCode() | Send SMS verification code details |
uniIdCo.sendEmailCode() | Send email verification code Details |
uniIdCo.refreshToken() | Refresh token Details |
uniIdCo.acceptInvite() | Accept the invitation details |
uniIdCo.getInvitedUser() | Get invited user Details |
uniIdCo.setPushCid() | Update the push_clien_id of the device table Details |
uniIdCo.getSupportedLoginType() | Get the supported login method Details |
Interface name: registerAdmin
Interface form
await uniIdCo.registerAdmin({
username,
password,
nickname
})
Parameter Description
Parameter Name | Type | Required | Description |
---|---|---|---|
username | string | yes | Super admin username |
password | string | yes | Super admin password |
nickname | string | No | Super Admin Nickname |
return value
parameter name | type | description |
---|---|---|
errCode | string|number | Error code |
errMsg | string | Error message |
|- token | string | token |
|- tokenExpired | string | token expiration time |
Notice
Interface name: registerUser
Interface form
await uniIdCo.registerUser({
username,
password,
captcha,
nickname,
inviteCode
})
Parameter Description
Parameter Name | Type | Required | Description |
---|---|---|---|
username | string | yes | username |
password | string | yes | password |
captcha | string | yes | graphic captcha |
nickname | string | no | nickname |
inviteCode | string | No | InviteCode |
return value
parameter name | type | description |
---|---|---|
errCode | string|number | Error code |
errMsg | string | Error message |
|- token | string | token |
|- tokenExpired | string | token expiration time |
Interface name: registerUserByEmail
Interface form
await uniIdCo.registerUserByEmail({
email,
password,
code,
nickname,
inviteCode
})
Parameter Description
Parameter Name | Type | Required | Description |
---|---|---|---|
string | Yes | ||
password | string | yes | password |
code | string | Yes | Email Verification Code |
nickname | string | no | nickname |
inviteCode | string | No | InviteCode |
return value
parameter name | type | description |
---|---|---|
errCode | string|number | Error code |
errMsg | string | Error message |
|- token | string | token |
|- tokenExpired | string | token expiration time |
Interface name: login
Interface form
await uniIdCo.login({
username,
password,
captcha
})
Parameter Description
Parameter Name | Type | Required | Description |
---|---|---|---|
username | string | choose one from mobile, email | username |
mobile | string | and username, email three choose one | mobile phone number |
string | and username, mobile choose one of three | ||
password | string | yes | password |
captcha | string | no | graphic captcha |
return value
parameter name | type | description |
---|---|---|
errCode | string|number | Error code |
errMsg | string | Error message |
|- token | string | token |
|- tokenExpired | string | token expiration time |
Login if the phone number already exists, otherwise register
Interface name: loginBySms
Interface form
await uniIdCo.loginBySms({
mobile,
code,
captcha,
inviteCode
})
Parameter Description
参数名 | 类型 | 必填 | 说明 |
---|---|---|---|
mobile | string | 是 | 手机号 |
code | string | 是 | 短信验证码 |
captcha | string | 否 | 图形验证码 |
inviteCode | string | No | Invite Code, only valid when registering |
两小时内登录失败3次的用户必填图形验证码,如果客户端没有使用uni-id-pages,可以参考uni-id-pages验证码登录页面的相关逻辑。
return value
parameter name | type | description |
---|---|---|
errCode | string|number | Error code |
errMsg | string | Error message |
|- token | string | token |
|- tokenExpired | string | token expiration time |
Interface name: loginByWeixinMobile
Interface form
await uniIdCo.loginByWeixinMobile({
phoneCode,
inviteCode
})
Parameter Description
Parameter name | Type | Required | Description |
---|---|---|---|
phoneCode | string | yes | getPhoneNumber event callback gets the dynamic token code |
inviteCode | string | No | Invitation code, valid only when registering |
return value
parameter name | type | description |
---|---|---|
errCode | string|number | error code |
errMsg | string | error message |
|- token | string | token |
|- tokenExpired | string | token expiration time |
Notice
Login if the phone number already exists, otherwise register
Interface name: loginByUniverify
Interface form
await uniIdCo.loginByUniverify({
access_token,
openid,
inviteCode
})
Parameter Description
Parameter Name | Type | Required | Description |
---|---|---|---|
access_token | string | yes | access_token returned by the one-click login client |
openid | string | yes | openid returned by one-click login client |
inviteCode | string | No | Invite Code, only valid when registering |
return value
parameter name | type | description |
---|---|---|
errCode | string|number | Error code |
errMsg | string | Error message |
|- token | string | token |
|- tokenExpired | string | token expiration time |
Login if the WeChat account already exists, otherwise register
Interface name: loginByWeixin
Interface form
await uniIdCo.loginByWeixin({
code,
inviteCode
})
Parameter Description
Parameter Name | Type | Required | Description |
---|---|---|---|
code | string | yes | The code parameter returned by the uni.login interface |
inviteCode | string | No | Invite Code, only valid when registering |
return value
parameter name | type | description |
---|---|---|
errCode | string|number | Error code |
errMsg | string | Error message |
|- token | string | token |
|- tokenExpired | string | token expiration time |
Notice
uni-id-pages 1.0.8
and later versions, when storing the openid, a copy of the current application's Appid (DCloud AppId in manifest.json) will be stored as the key. openid, see the description of openid below.uni-id-pages 1.0.8
and above will use uni-open-bridge-common to save session_key
(WeChat MiniApp login), access_token
(WeChat official account login, WeChat App login), these information, However, a copy is still stored in the user table for compatibility with legacy logic. Detailed reference: Automatically save user sessionKey, accessToken and other informationuni-id-pages 1.0.7
and earlier versions will save WeChat's openid in the following format
{
"_id": "xx",
"wx_openid": {
"mp": "weixin-openid-demo"
}
}
It can be seen that if there are multiple WeChat applet applications connected to an uniCloud background and associated with the same account, only the openid of one applet can be stored at this time.
This has been adjusted and corrected in the uni-id-pages 1.0.8
version, and multiple DCloud Appids can correspond to different WeChat openids. Taking Appid__UNI_123456
as an example, the openid will be stored in the database in the following form:
{
"_id": "xx",
"wx_openid": {
"mp": "weixin-openid-demo",
"mp___UNI_123456": "weixin-openid-demo",
}
}
Log in if the QQ account already exists, otherwise register
Interface name: loginByQQ
Interface form
await uniIdCo.loginByQQ({
code,
accessToken,
inviteCode
})
Parameter Description
Parameter Name | Type | Required | Description |
---|---|---|---|
code | string | No | code parameter returned by QQ applet uni.login |
accessToken | string | No | accessToken parameter returned by QQ login on the APP side |
accessTokenExpired | number | No | accessToken expiration time, the expires_in parameter returned by QQ login on the APP side |
inviteCode | string | No | Invite Code, only valid when registering |
return value
parameter name | type | description |
---|---|---|
errCode | string|number | Error code |
errMsg | string | Error message |
|- token | string | token |
|- tokenExpired | string | token expiration time |
Notice
uni-id-pages 1.0.8
and later versions, when storing the openid, a copy of the current application's Appid (DCloud AppId in manifest.json) will be stored as the key. openid, see the description of openid below.uni-id-pages 1.0.8
and above will use uni-open-bridge-common to save session_key (QQ applet login), access_token (QQ App login) information, but for compatibility with the old version logic is still in the user table A copy is stored. For details, please refer to: Automatically save user sessionKey, accessToken and other informationNote about openid
uni-id-pages 1.0.7
and earlier versions will store QQ's openid in the following form
{
"_id": "xx",
"qq_openid": {
"mp": "weixin-openid-demo"
}
}
It can be seen that if there are multiple QQ applets associated with the same account, only the openid of one applet can be stored at this time. This has been adjusted in the uni-id-pages 1.0.8
version. Take Appid__UNI_123456
as an example , the openid will be stored in the database as the following
{
"_id": "xx",
"qq_openid": {
"mp": "weixin-openid-demo",
"mp___UNI_123456": "weixin-openid-demo",
}
}
Login when Alipay account already exists, otherwise register
Interface name: loginByAlipay
Interface form
await uniIdCo.loginByAlipay({
code,
inviteCode
})
Parameter Description
Parameter Name | Type | Required | Description |
---|---|---|---|
code | string | Yes | The code parameter returned by the Alipay applet uni.login |
inviteCode | string | No | Invite Code, only valid when registering |
return value
parameter name | type | description |
---|---|---|
errCode | string|number | Error code |
errMsg | string | Error message |
|- token | string | token |
|- tokenExpired | string | token expiration time |
Log in if the Apple account already exists, otherwise register
Interface name: loginByApple
Interface form
await uniIdCo.loginByApple({
identityToken,
nickname,
inviteCode
})
Parameter Description
Parameter Name | Type | Required | Description |
---|---|---|---|
identityToken | string | Yes | The identityTokenc parameter returned by Apple login on the App side |
nickname | string | no | nickname |
inviteCode | string | No | Invite Code, only valid when registering |
return value
parameter name | type | description |
---|---|---|
errCode | string|number | Error code |
errMsg | string | Error message |
|- token | string | token |
|- tokenExpired | string | token expiration time |
Interface name: logout
Interface form
await uniIdCo.logout()
Parameter Description
none
return value
parameter name | type | description |
---|---|---|
errCode | string|number | Error code |
errMsg | string | Error message |
After calling this interface, the user status will be set to the logout state. It should be noted that the token will not be automatically invalidated at present, and redis will be introduced to solve this problem in the future. If this function is not required, it is recommended to modify the code manually.
Interface name: closeAccount
Interface form
await uniIdCo.closeAccount()
Parameter Description
none
return value
parameter name | type | description |
---|---|---|
errCode | string|number | Error code |
errMsg | string | Error message |
Interface name: getSupportedLoginType
Interface form
await uniIdCo.getSupportedLoginType()
Parameter Description
none
return value
parameter name | type | description |
---|---|---|
errCode | string|number | Error code |
errMsg | string | Error message |
supportedLoginType | array | List of supported login methods, see description below |
supportedLoginType
Login | Instructions |
---|---|
username-password | Login with username and password |
mobile-password | Mobile phone number password login |
email-password | Email password login |
mobile-code | Mobile phone number verification code login |
univerify | App one-click login |
weixin | WeChat Login |
QQ login | |
apple | Apple Login |
alipay | Alipay login |
Interface name: bindMobileBySms
Interface form
await uniIdCo.bindMobileBySms({
mobile,
code,
captcha
})
Parameter Description
Parameter Name | Type | Required | Description |
---|---|---|---|
mobile | string | yes | mobile number |
code | string | Yes | SMS verification code |
captcha | string | No | Captcha |
return value
parameter name | type | description |
---|---|---|
errCode | string|number | Error code |
errMsg | string | Error message |
|- token | string | token |
|- tokenExpired | string | token expiration time |
Notice
Interface name: bindMobileByUniverify
Interface form
await uniIdCo.bindMobileByUniverify({
openid,
access_token
})
Parameter Description
Parameter Name | Type | Required | Description |
---|---|---|---|
openid | string | Yes | The openid parameter returned by the client's one-click login |
access_token | string | Yes | access_token parameter returned by the client's one-click login |
return value
parameter name | type | description |
---|---|---|
errCode | string|number | Error code |
errMsg | string | Error message |
|- token | string | token |
|- tokenExpired | string | token expiration time |
Notice
Be careful when using this interface
**The WeChat MiniApp has upgraded the security of the interface for obtaining the mobile phone number. Starting from uni-id-co@1.0.25
, the dynamic password code
for the getPhoneNumber event callback is supported, and it is reserved for backward compatibilityencryptedData
and iv
parameters, it is recommended that developers upgrade to enhance the security of MiniApp. **
The rule of the WeChat MiniApp is that the client should first use the checkSession interface to check whether the sessionKey obtained last time is still valid.
If it is valid, you can directly use the sessionKey stored last time. If it is invalid, call the login interface again to refresh the sessionKey again.
The user's sessionKey will be automatically updated when the WeChat applet logs in and binds the WeChat account of the applet.
Interface name: bindMobileByMpWeixin
Interface form
// uni-id-co >= 1.0.25
await uniIdCo.bindMobileByMpWeixin({
code
})
// uni-id-co < 1.0.25
await uniIdCo.bindMobileByMpWeixin({
encryptedData,
iv
})
Parameter Description
Parameter Name | Type | Required | Description |
---|---|---|---|
encryptedData | string | Yes | The encryptedData parameter returned by the WeChat MiniApp to obtain the mobile phone number |
iv | string | yes | the iv parameter returned by the WeChat MiniApp to obtain the mobile phone number |
code | string | yes | the code parameter returned by the WeChat MiniApp to obtain the mobile phone number; uni-id-co >= 1.0.25 support |
return value
parameter name | type | description |
---|---|---|
errCode | string|number | Error code |
errMsg | string | Error message |
|- token | string | token |
|- tokenExpired | string | token expiration time |
Notice
Interface name: bindWeixin
Interface form
await uniIdCo.bindWeixin({
code
})
Parameter Description
Parameter Name | Type | Required | Description |
---|---|---|---|
code | string | Yes | Code parameter returned by WeChat login |
return value
parameter name | type | description |
---|---|---|
errCode | string|number | Error code |
errMsg | string | Error message |
|- token | string | token |
|- tokenExpired | string | token expiration time |
Notice
Interface name: bindQQ
Interface form
await uniIdCo.bindQQ({
code,
accessToken
})
Parameter Description
Parameter Name | Type | Required | Description |
---|---|---|---|
code | string | No | code parameter returned by QQ applet login |
accessToken | string | No | accessToken parameter returned by QQ login on the app side |
return value
parameter name | type | description |
---|---|---|
errCode | string|number | Error code |
errMsg | string | Error message |
|- token | string | token |
|- tokenExpired | string | token expiration time |
Notice
Interface name: bindAlipay
Interface form
await uniIdCo.bindAlipay({
code
})
Parameter Description
Parameter Name | Type | Required | Description |
---|---|---|---|
code | string | Yes | Code parameter returned by Alipay applet login |
return value
parameter name | type | description |
---|---|---|
errCode | string|number | Error code |
errMsg | string | Error message |
|- token | string | token |
|- tokenExpired | string | token expiration time |
Notice
Interface name: bindApple
Interface form
await uniIdCo.bindApple({
identityToken
})
Parameter Description
Parameter Name | Type | Required | Description |
---|---|---|---|
identityToken | string | Yes | identityToken parameter returned by Apple login |
return value
parameter name | type | description |
---|---|---|
errCode | string|number | Error code |
errMsg | string | Error message |
|- token | string | token |
|- tokenExpired | string | token expiration time |
Notice
If there is only one third-party login method for the account, it is necessary to bind the mobile phone number and then unbind it.
Interface name: unbindWeixin
Interface form
await uniIdCo.unbindWeixin()
return value
parameter name | type | description |
---|---|---|
errCode | string|number | error code |
errMsg | string | error message |
Interface name: unbindQQ Interface form
await uniIdCo.unbindQQ()
return value
parameter name | type | description |
---|---|---|
errCode | string|number | error code |
errMsg | string | error message |
Interface name: unbindAlipay Interface form
await uniIdCo.unbindAlipay()
return value
parameter name | type | description |
---|---|---|
errCode | string|number | error code |
errMsg | string | error message |
Interface name: unbindApple Interface form
await uniIdCo.unbindApple()
return value
parameter name | type | description |
---|---|---|
errCode | string|number | error code |
errMsg | string | error message |
Interface name: setPwd
Interface form
await uniIdCo.setPwd({
code,
captcha,
password
})
Parameter Description
Parameter name | Type | Required | Description |
---|---|---|---|
code | string | Yes | Mobile phone verification code |
captcha | string | no | graphic verification code |
password | string | yes | password |
return value
parameter name | type | description |
---|---|---|
errCode | string|number | error code |
Interface name: updatePwd
Interface form
await uniIdCo.updatePwd({
oldPassword,
newPassword
})
Parameter Description
Parameter Name | Type | Required | Description |
---|---|---|---|
oldPassword | string | Yes | Old Password |
newPassword | string | Yes | NewPassword |
return value
parameter name | type | description |
---|---|---|
errCode | string|number | Error code |
errMsg | string | Error message |
|- token | string | token |
|- tokenExpired | string | token expiration time |
Notice
Interface name: resetPwdBySms
Interface form
await uniIdCo.resetPwdBySms({
mobile,
code,
password,
captcha
})
Parameter Description
Parameter Name | Type | Required | Description |
---|---|---|---|
mobile | string | yes | mobile number |
code | string | Yes | SMS verification code |
password | string | yes | password |
captcha | string | no | graphic captcha |
return value
parameter name | type | description |
---|---|---|
errCode | string|number | error code |
errMsg | string | error message |
Interface name: resetPwdByEmail
Interface form
await uniIdCo.resetPwdByEmail({
email,
code,
password,
captcha
})
Parameter Description
Parameter Name | Type | Required | Description |
---|---|---|---|
string | Yes | ||
code | string | Yes | Email Verification Code |
password | string | yes | password |
captcha | string | no | graphic captcha |
return value
parameter name | type | description |
---|---|---|
errCode | string|number | Error code |
errMsg | string | Error message |
Interface name: getAccountInfo
Interface form
await uniIdCo.getAccountInfo()
Parameter Description
none
return value
parameter name | type | description |
---|---|---|
errCode | string|number | Error code |
errMsg | string | Error message |
isUsernameSet | boolean | Whether there is a username |
isNicknameSet | boolean | Is there already a nickname |
isPasswordSet | boolean | Is a password set |
isMobileBound | boolean | Whether the mobile phone number is bound |
isEmailBound | boolean | Email is bound |
isWeixinBound | boolean | Whether WeChat is bound |
isQQBound | boolean | Whether QQ is bound |
isAlipayBound | boolean | Is Alipay bound |
isAppleBound | boolean | Is Apple account bound |
Interface name: acceptInvite
Interface form
await uniIdCo.acceptInvite({
inviteCode
})
Parameter Description
Parameter Name | Type | Required | Description |
---|---|---|---|
inviteCode | string | yes | inviteCode |
return value
parameter name | type | description |
---|---|---|
errCode | string|number | Error code |
errMsg | string | Error message |
|- token | string | token |
|- tokenExpired | string | token expiration time |
Notice
Interface name: getInvitedUser
Interface form
await uniIdCo.getInvitedUser({
level,
limit,
offset,
needTotal
})
Parameter Description
Parameter Name | Type | Required | Description |
---|---|---|---|
level | number | Yes | Invite user level, for example, when the value is 1, it means the user you directly invite |
limit | number | No | The number returned by this request, default: 20 |
offset | number | No | List offset value, default: 0, paging by combining with limit |
needTotal | boolean | no | whether to return the total number, default: false |
return value
parameter name | type | description |
---|---|---|
errCode | string|number | Error code |
errMsg | string | Error message |
|- token | string | token |
|- tokenExpired | string | token expiration time |
Notice
接口名:getRealNameInfo
接口形式
await uniIdCo.getRealNameInfo({
decryptData
})
参数说明
参数名 | 类型 | 必填 | 说明 |
---|---|---|---|
decryptData | boolean | 否 | 是否解密数据;默认:true |
返回值
参数名 | 类型 | 说明 |
---|---|---|
errCode | string|number | 错误码 |
errMsg | string | 错误信息 |
type | number | 用户类型:0 个人用户 1 企业用户 |
authStatus | number | 认证状态:0 未认证 1 等待认证 2 认证通过 3 认证失败 |
realName | string | 姓名(脱敏);用户类型为 0 时返回 |
identity | string | 身份证号码(脱敏);用户类型为 0 时返回 |
注意
在uni-id-pages中默认启用敏感数据加解密,如果开发者没有使用uni-id提供的敏感信息加密功能,请将decryptData
参数改为false
,返回原始信息
Interface name: createCaptcha
Interface form
await uniIdCo.createCaptcha({
scene
})
Parameter Description
Parameter Name | Type | Required | Description |
---|---|---|---|
scene | string | yes | The scene where the graphic verification code is used. Make sure that the scene where the verification code is used matches the scene parameters passed when generating the verification code, otherwise the verification will fail. Refer to: [Graphic verification code scene](uni- id-summary.md#captcha-scene) |
return value
parameter name | type | description |
---|---|---|
errCode | string|number | Error code |
errMsg | string | error message |
captchaBase64 | string | Captcha: base64 format |
Interface name: refreshCaptcha
Interface form
await uniIdCo.refreshCaptcha({
scene
})
Parameter Description
Parameter Name | Type | Required | Description |
---|---|---|---|
scene | string | Yes | The usage scenario of the captcha, refer to: Graphic captcha scene |
return value
parameter name | type | description |
---|---|---|
errCode | string|number | Error code |
errMsg | string | error message |
captchaBase64 | string | Captcha: base64 format |
The function of sending SMS requires the following pre-work
Interface name: sendSmsCode
Interface form
await uniIdCo.sendSmsCode({
mobile,
captcha,
scene
})
Parameter Description
Parameter Name | Type | Required | Description |
---|---|---|---|
mobile | string | yes | mobile number |
captcha | string | yes | graphic verification code |
scene | string | yes | The scene where the SMS verification code is used, make sure that the scene where the verification code is used matches the scene parameters passed when sending the verification code, otherwise the verification will fail, refer to: [SMS verification code usage scene](uni -id-summary.md#sms-scene) |
return value
parameter name | type | description |
---|---|---|
errCode | string|number | error code |
errMsg | string | error message |
Interface name: sendEmailCode
Interface form
await uniIdCo.sendEmailCode({
email,
captcha,
scene
})
Parameter Description
Parameter Name | Type | Required | Description |
---|---|---|---|
string | Yes | ||
captcha | string | yes | graphic verification code |
scene | string | yes | use scene, refer to: mobile phone, email verification code use scene |
return value
parameter name | type | description |
---|---|---|
errCode | string|number | Error code |
errMsg | string | Error message |
Interface name: refreshToken
Interface form
await uniIdCo.refreshToken()
Parameter Description
none
return value
parameter name | type | description |
---|---|---|
errCode | string|number | Error code |
errMsg | string | Error message |
|- token | string | token |
|- tokenExpired | string | token expiration time |
If you are not using uni-push 2.0
, you don't need to pay attention to this interface. This interface is used to update the unipush_clientid field of the uni-id-device table, which is used to push messages by client, user and other dimensions
Interface name: setPushCid
Interface form
await uniIdCo.setPushCid({
pushClientId
})
Parameter Description
Parameter Name | Type | Required | Description |
---|---|---|---|
pushClientId | string | Yes | The clientId corresponding to the uni-push obtained by the client |
return value
parameter name | type | description |
---|---|---|
errCode | string|number | Error code |
errMsg | string | Error message |
|- token | string | token |
|- tokenExpired | string | token expiration time |
This interface is used for the handshake of the secure network on the WeChat MiniApp side. For related documents on the secure network, please refer to: secure-network
Generally, there is no need to call through uniCloud.importObject. When the client calls uniCloud.initSecureNetworkByWeixin()
, session-related information will be obtained through this interface.
This interface will store the session information in the opendb-open-data
table. If callLoginByWeixin: true
is passed in the initSecureNetworkByWeixin
method, it will execute a loginByWeixin
of uni-id-co while storing the session information method
Interface name: addUser
Interface form
await uniIdCo.addUser({
username,
password,
authorizedApp,
nickname,
role
})
Parameter Description
Parameter name | Type | Required | Description |
---|---|---|---|
username | string | yes | username |
password | string | yes | password |
authorizedApp | Array<string> | No | A list of apps that allow login |
nickname | string | no | nickname |
role | Array<string> | No | User role |
mobile | string | No | Mobile phone number |
string | no | ||
tags | array | no | user tags |
status | number | No | User status, refer to: User Status |
return value
parameter name | type | description |
---|---|---|
errCode | string|number | Error code |
errMsg | string | Error message |
接口名:updateUser
接口形式
await uniIdCo.updateUser({
uid,
username,
password,
nickname,
authorizedApp,
role,
mobile,
email,
tags,
status
})
参数说明
参数名 | 类型 | 必填 | 说明 |
---|---|---|---|
uid | string | 是 | 要更新的用户id |
username | string | 是 | 用户名 |
password | string | 否 | 密码 |
nickname | string | 否 | 昵称 |
authorizedApp | Array<string> | 否 | 允许登录的app列表 |
role | Array<string> | 否 | 用户角色 |
mobile | string | 否 | 手机号 |
string | 否 | 邮箱 | |
tags | array | 否 | 用户标签 |
status | number | 否 | 用户状态,参考:用户状态 |
返回值
参数名 | 类型 | 说明 |
---|---|---|
errCode | string|number | 错误码 |
errMsg | string | 错误信息 |
Interface name: authorizeAppLogin
Interface form
await uniIdCo.authorizeAppLogin({
uid,
appId
})
Parameter Description
Parameter Name | Type | Required | Description |
---|---|---|---|
uid | string | yes | userid |
appId | string | yes | DCloud AppId of the app allowed to log in |
return value
parameter name | type | description |
---|---|---|
errCode | string|number | Error code |
errMsg | string | Error message |
|- token | string | token |
|- tokenExpired | string | token expiration time |
Notice
Interface name: removeAuthorizedApp
Interface form
await uniIdCo.removeAuthorizedApp({
uid,
appId
})
Parameter Description
Parameter Name | Type | Required | Description |
---|---|---|---|
uid | string | yes | userid |
appId | string | yes | DCloud AppId of the app for which login is prohibited |
return value
parameter name | type | description |
---|---|---|
errCode | string|number | Error code |
errMsg | string | Error message |
|- token | string | token |
|- tokenExpired | string | token expiration time |
Notice
Interface name: setAuthorizedApp
Interface form
await uniIdCo.setAuthorizedApp({
uid,
appIdList
})
Parameter Description
Parameter Name | Type | Required | Description |
---|---|---|---|
uid | string | yes | userid |
appIdList | Array<String> | Yes | The list of DCloud AppIds corresponding to the applications allowed to log in |
return value
parameter name | type | description |
---|---|---|
errCode | string|number | Error code |
errMsg | string | Error message |
|- token | string | token |
|- tokenExpired | string | token expiration time |
Notice
适合自己有用户系统,同时需要使用依赖UniId的业务,将自身系统的用户账号导入uniId,为其创建一个对应uniId的账号,使得该账号可以使用依赖uniId的系统及功能。 由于此方案的接口不需要密码验证,开发者务必要保证接口只能在服务端调用,同时要求在请求时计算签名来保证安全。
联登相关接口只支持HTTP方式调用,调用时需要携带鉴权签名值,查看URL化请求鉴权签名计算
外部用户注册,注册成功后,uni-id 返回 uid 与 用户 token ,请务必在自身系统中维护好 uid 与 token。
接口地址
POST /your-uni-id-co-path/externalRegister
HTTP 示例
POST /your-uni-id-co-path/externalRegister HTTP/1.1
Host: xxx.com
uni-id-nonce: xxxxxxx
uni-id-timestamp: 1676882808550
uni-id-signature: 11c965267a4a02c6978949c7135215b0a75aea22b2b84ed491e792365c8269efa
Content-Type: application/json
Cache-Control: no-cache
{"externalUid": "test externalUid", "nickname": "张三", "avatar": "xxxxxxx", "gender": 0}
注意
Request Body 说明
参数名 | 类型 | 必填 | 说明 |
---|---|---|---|
externalUid | string | 是 | 自身系统的用户id,必须保证唯一性。 |
nickname | string | 否 | 用户昵称 |
avatar | string | 否 | 用户头像 |
gender | number | 否 | 用户性别;0 未知 1 男性 2 女性 |
Response Body 说明
parameter name | type | description |
---|---|---|
errCode | string|number | error code |
errMsg | string | error message |
|- token | string | token |
|- tokenExpired | string | token过期时间 |
externalUid | string | 自身系统的用户id |
uid | string | uni-id体系的用户Id |
nickname | string | 用户昵称 |
avatar | string | 用户头像 |
gender | string | 用户性别;0 未知 1 男性 2 女性 |
External user login, used to obtain user token
接口地址
POST /your-uni-id-co-path/externalLogin
HTTP 示例
POST /your-uni-id-co-path/externalLogin HTTP/1.1
Host: xxx.com
uni-id-nonce: xxxxxxx
uni-id-timestamp: 1676882808550
uni-id-signature: 11c965267a4a02c6978949c7135215b0a75aea22b2b84ed491e792365c8269efa
Content-Type: application/json
Cache-Control: no-cache
{"externalUid": "test externalUid"}
注意
Request Body 说明
Parameter name | Type | Required | Description |
---|---|---|---|
uid | string | 否 | uni-id体系的用户Id;与externalUid 二选一 |
externalUid | string | 否 | 自身系统的用户id;与 uid 二选一 |
Response Body 说明
parameter name | type | description |
---|---|---|
errCode | string|number | error code |
errMsg | string | error message |
|- token | string | token |
|- tokenExpired | string | token过期时间 |
uid | string | uni-id体系的用户Id |
外部用户修改账号信息,如用户在自身系统内修改了用户信息后,通过此接口同步修改uni-id中用户信息。
接口地址
POST /your-uni-id-co-path/updateUserInfoByExternal
HTTP 示例
POST /your-uni-id-co-path/updateUserInfoByExternal HTTP/1.1
Host: xxx.com
uni-id-nonce: xxxxxxx
uni-id-timestamp: 1676882808550
uni-id-signature: 11c965267a4a02c6978949c7135215b0a75aea22b2b84ed491e792365c8269efa
Content-Type: application/json
Cache-Control: no-cache
{"externalUid": "test externalUid", "nickname": "张三"}
注意
Request Body 说明
参数名 | 类型 | 必填 | 说明 |
---|---|---|---|
uid | string | 否 | uni-id体系的用户Id;与externalUid 二选一 |
externalUid | string | 否 | 自身系统的用户id;与 uid 二选一 |
username | string | 否 | 用户名 |
password | string | 否 | 密码 |
nickname | string | 否 | 昵称 |
authorizedApp | Array<string> | 否 | 允许登录的app列表 |
role | Array<string> | 否 | 用户角色 |
mobile | string | 否 | 手机号 |
string | 否 | 邮箱 | |
tags | array | 否 | 用户标签 |
status | number | 否 | 用户状态,参考:用户状态 |
avatar | string | 否 | 用户头像 |
gender | number | 否 | 用户性别;0 未知 1 男性 2 女性 |
Response Body 说明
参数名 | 类型 | 说明 |
---|---|---|
errCode | string|number | 错误码 |
errMsg | string | 错误信息 |
实人认证相关功能建议或问题,可以加入uni-im交流群进行讨论,点此加入
基于实人认证服务实现,实现用户刷脸核验真实身份,完成实名认证。
uni-id-pages
已内置实人认证前端页面与云端云对象,了解如在uni-id-pages
中使用。
接口名:getFrvCertifyId
接口形式
await uniIdCo.getFrvCertifyId({
realName,
idCard,
metaInfo
})
参数说明
参数名 | 类型 | 必填 | 说明 |
---|---|---|---|
realName | string | 是 | 用户真实姓名 |
idCard | string | 是 | 用户身份证号码 |
metaInfo | String | 是 | 客户端初始化时返回的metaInfo |
返回值
参数名 | 类型 | 说明 |
---|---|---|
errCode | string|number | 错误码 |
errMsg | string | 错误信息 |
certifyId | object | 认证Id;用于客户端调用认证接口及云函数获取认证结果 |
接口名:getFrvAuthResult
接口形式
await uniIdCo.getFrvAuthResult({
certifyId
})
参数说明
参数名 | 类型 | 必填 | 说明 |
---|---|---|---|
certifyId | string | 是 | 认证Id |
返回值
参数名 | 类型 | 说明 |
---|---|---|
errCode | string|number | 错误码 |
errMsg | string | 错误信息 |
authStatus | number | 认证状态:0 未认证 1 等待认证 2 认证通过 3 认证失败 |
realName | string | 姓名(脱敏);敏感信息加密参考 |
identity | string | 身份证号码(脱敏);敏感信息加密参考 |
uni-id-co mounts the validator instance on the this of the cloud object. After obtaining the validator instance from uni-id-co/index.obj.js, you can use the mixin method of the validator instance to overwrite or add validation rules.
Interface form: validator.mixin(String type, Function handler)
. Where type is the rule type (string), handler is the verification function
// uni-id-co/index.obj.js
const {
Validator
} = require('./common/validator.js')
module.exports = {
_before () {
this.validator = new Validator()
/**
* 示例:覆盖密码验证规则
*/
this.validator.mixin('password', function (password) {
if (typeof password !== 'string' || password.length < 10) {
// 调整为密码长度不能小于10
return {
errCode: ERROR.INVALID_PASSWORD
}
}
})
/**
* 示例:新增验证规则
*/
this.validator.mixin('timestamp', function (timestamp) {
if (typeof timestamp !== 'number' || timestamp > Date.now()) {
return {
errCode: ERROR.INVALID_PARAM
}
}
})
// // 新增规则同样可以在数组验证规则中使用
this.validator.valdate({
timestamp: 123456789
}, {
timestamp: 'timestamp'
})
this.validator.valdate({
timestampList: [123456789, 123123123123]
}, {
timestampList: 'array<timestamp>'
})
// // 甚至更复杂的写法
this.validator.valdate({
timestamp: [123456789, 123123123123]
}, {
timestamp: 'timestamp|array<timestamp>'
})
}
}
The key information of the server uni-id
is uniformly configured in uni-config-center
, the path: uni_modules/uni-config-center/uniCloud/cloudfunctions/common/uni-config-center/uni-id/ config.json
Hereinafter referred to as: uni-id configuration file
, complete configuration information see details
One-click login is a more convenient, safer, and cheaper solution than SMS verification codes provided by operators. See for details.
manifest.json
-->App module configuration
-->OAuth (login authentication)
-->One-click login
, click on the back of Activate configuration
, and then open the web In the interface, agree to the agreement, and click the recharge button to recharge. If it is just a test, you can only recharge 1 yuan. If you have determined the package name, you can click "Add Application" on the web interface to submit for review. This is required for official packaging. You can skip this link in real machine operation. Remember the apiKey
and apiSecret
shown on the page, which will be used in the next step.uni-id configuration file
--> service
--> univerify
, fill in appid
, apiKey
and apiSecret
. appid
is the appid
in the manifest
. apiKey
and apiSecret
are obtained from the web interface in the previous step.uni-id-pages has fully supported: app, applet, web (from uni-id-pages version 1.0.8), WeChat login on three terminals.
WeChat divides applications into 4 categories:
The website application
and official account
here are both for web applications, accessing the WeChat login function. But there are the following differences:
Hosting Environment | Type | Login Method |
---|---|---|
WeChat APP | Official Account | Website Authorized Login |
Ordinary browser | Website application | Mobile WeChat scan code login |
WeChat
, whether it is a WeChat applet or WeChat official account H5, it belongs to WeChat Public Platform.WeChat
, whether it is other apps or other webpages outside WeChat, it belongs to WeChat Open Platform.You can open a corresponding platform account according to your needs.
Notice
If your application has multiple ends, realize unified identification, information synchronization and behavior tracking of the same user in different scenarios such as official accounts, mini programs, APPs, official websites, etc.
(For details, please refer to: "UnionID Association" Function Introduction and Operation Suggestions)
It is necessary to bind the Mini Program
and Official Account
to the same WeChat Open Platform Account
.
Management Center
-> select Official Account/Mini Program
-> Click `Bind Official Account/ appletmanifest.json
-> App module configuration
-> OAuth (login authentication)
-> Check WeChat login
-> fill in appid
, ios platform universal link
.manifest.json
-> WeChat Mini Program Configuration
-> Fill in WeChat Mini Program AppID/uni_modules/uni-id-pages/config.js
-> appid
-> weixin
Configure the appid of the WeChat public account on the h5
node, and configure the WeChat open platform creation on the web
node web application appiduni-id
is uniformly configured in uni-config-center
, path: uniCloud/cloudfunctions/common/uni-config-center/uni-id/config.json
, complete Configuration information details view登录的流程为:
loginByWeiXin
method of the uni-id-co
cloud object, and get the token
to complete the loginappid
说明:微信app内打开的网页,为公众号的appid。其他场景则为在微信开放平台
创建的网站应用
的appid。redirect_uri
description: The website link returned after entering the authorization page. The domain name of this link needs to be configured in the service background first. For details, see: Configuration of the callback domain nameExample code is already provided in the uni-id-pages plugin.
手机微信扫码登录
微信开放平台 -> 管理中心 -> 网站应用 -> 选择对应的应用名称,点击查看 -> 开发信息,点击修改 -> 填写授权回调域
基于微信公众号auth登录
登录微信公众号 -> 设置与开发 -> 公众号设置 -> 设置网页授权域名
To call back the domain name, you must access the URL address that has been registered on the external network. Otherwise, debugging cannot be performed locally. You can do intranet penetration and map to generate an external network URL address for callback testing. But that is more troublesome, here we introduce a method to start a Web Server locally for debugging based on HBuilderX.
manifest.json
-> H5 configuration
-> port
-> enter 80
Note: In the mac system, non-root users cannot use common ports less than 1024. Solution Open
Terminal
, cd to the HBuilderX installation directory (the default is Applications directory, executecd /Applications
), then executesudo ./HBuilderX.app/Contents/MacOS/HBuilderX
, enter the power-on password, and press Enter , HBuilderX will be reopened with root user privileges;
If port 80 is not enabled but 81, etc., your port is occupied. You have two options: 1. Close the suspicious program, or restart the computer directly. 2. Close the port occupied by the command line [Details](https://www.baidu.com/s?&wd=%E5%91%BD%E4 %BB%A4%E8%A1%8C%20%E8%A7%A3%E5%86%B3%E7%AB%AF%E5%8F%A3%E8%A2%AB%E5%8D%A0%E7 %94%A8)
C:\Windows\System32\drivers\etc
。mac系统:/etc/
127.0.0.1 你的域名
保存即可。
此时访问域名,如果就能看到和你的项目运行到浏览器一样的效果,说明已经成功了。manifest.json
--> App module configuration
--> OAuth (login authentication) check Apple login
, [IOS Apple Authorized Login Reference Document](https://ask.dcloud. net.cn/article/36651). If you do not publish to the Appstore, you do not need to configure thisuni-id configuration file
--> app
--> oauth
--> apple
Fill in bundleId
.manifest.json
--> App common other settings
--> iOS settings
--> Associated Domains
Fill in the configuration [Reference Tutorial](https://ask. dcloud.net.cn/article/36393). If you do not publish to the Appstore, you do not need to configure this为了方便开发调试,uni-id-pages
未配置短信登录时,自动启动测试模式;直接使用:123456作为短信验证码即可。
uni-id configuration file
--> service
--> sms
Fill in the relevant key information.Before HBuilderX 3.5, DCloud provided a common module uni-id (not to be confused with uni-id-common) and an example Cloud function uni-id-cf (integrated in uni-starter and uni-admin).
The old public module uni-id is a large and comprehensive account management public module, which is too large to be referenced by other cloud functions . For example, a business cloud function needs to verify the user token, and the referenced uni-id public module also contains the code for forgetting the password, which is a waste of resources.
From HBuilder 3.5 onwards, both uni-id and uni-id-cf will be phased out and will no longer be updated. The old common module uni-id was disassembled and turned into uni-id-common public module and uni-id-co cloud object .
uni-id-common is very compact, including only tokens and permissions, and is suitable for being referenced by all cloud functions.
uni-id-co is a more complete and standardized user-managed cloud object than uni-id-cf.
Then DCloud introduced uni-id-pages
.
At present, uni-starter and uni-admin still use the old version uni-id and uni-id-cf. User management for uni-id-pages is upgraded.
Significant changes have been made in this upgrade, most of the interfaces have been removed from public modules and implemented by uni-id-co instead. Only the interfaces for creating token, refreshing token, and verifying token remain in the uni-id public module. In addition to interface adjustments, the uni-id system (including uni-id public modules, uni-id-co) has the following adjustments:
preferedAppPlatform
, preferedWebPlatform
no longer take effect, inside uni-id, app
will be used instead of app-plus
, and web
will be used instead of h5
Field name adjustment
belowField name adjustment
below.When uni-id is upgraded to uni-id-co + uni-id-common, individual fields need to be renamed, and the changed fields can be renamed by directly running the following cloud function. In addition, you need to modify the index, delete the index of the old field, and add the index of the new field. It is recommended to operate in the early morning or other low-peak periods to avoid database operations taking too long to affect online users. (In the actual data test, 50,000 user records took about 5 seconds to rename the field)
'use strict';
const db = uniCloud.database()
const dbCmd = db.command
exports.main = async (event, context) => {
await db.collection('uni-id-users').update({
wx_openid: {
'app-plus': dbCmd.rename('wx_openid.app'), // app端微信openid
'mp-weixin': dbCmd.rename('wx_openid.mp'), // 小程序端微信openid
'h5-weixin': dbCmd.rename('wx_openid.h5'), // 微信公众号端微信openid
'h5-web': dbCmd.rename('wx_openid.web') // web端微信openid
},
qq_openid: {
'app-plus': dbCmd.rename('qq_openid.app'), // app端QQ openid
'mp-qq': dbCmd.rename('qq_openid.mp') // 小程序端QQ openid
}
})
return {}
};
uni-id-co@1.1.10
及以上版本支持使用uni-cloud-s2s
进行请求签名验证,uni-cloud-s2s
使用方式详见
uni-id-co
请求鉴权签名与uni-cloud-s2s
不能同时存在,如果存在uni-cloud-s2s
,则会优先使用uni-cloud-s2s
进行请求签名验证
uni-id-co 在URL化请求时,会对以下 API 进行调用鉴权验证,
在调用 API 时,开发者需要使用请求鉴权密钥(详见配置文件)requestAuthSecret
按照 uni-id 的约定方式对请求中的关键数据进行签名值计算,
And add the signature value to the uni-id-signature
parameter of the Header request header and pass it to uni-id for signature verification, and uni-id will calculate the signature value for the received data,
And compare it with the received request signature value, if the signature value is inconsistent, it will be regarded as an invalid signature, and the request will be rejected.
List of APIs that need to be signed
API |
---|
externalRegister |
externalLogin |
parameter name | type | required | description |
---|---|---|---|
uni-id-nonce | string | is a | random string |
uni-id-timestamp | string | yes | current timestamp; in milliseconds |
uni-id-signature | string | yes | request authentication signature; signature algorithm see below |
如下为某请求体参数,介绍如何进行签名:
{
"clientInfo": {
"appId": "__test__"
},
"uniIdToken": "xxxxxx",
"params": {
"foo": 1,
"bar": 2,
"foo_bar": 3,
"foobar": 4
}
}
params
参数,但除去array与object类型的参数),根据参数名称的ASCII码表的顺序排序。如:foo:1, bar:2, foo_bar:3, foobar:4
排序后的顺序是 bar:2, foo:1, foo_bar:3, foobar:4
key1=value1&key2=value2
format, the result obtained according to the above example is: bar=2&foo=1&foo_bar=3&foobar=4
HmacSHA256( timestamp + bar=2&foo=1&foo_bar=3&foobar=4, requestAuthSecret + nonce)
Hex.stringify(Utf8.parse("helloworld")) = "68656C6C6F776F726C64"
const crypto = require('crypto')
class Sign {
constructor (requestAuthSecret) {
this.requestAuthSecret = requestAuthSecret
}
getSignature (params, nonce, timestamp) {
const paramsStr = this.getParamsString(params)
const signature = crypto.createHmac('sha256', `${requestAuthSecret}${nonce}`).update(`${timestamp}${paramsStr}`).digest('hex')
return signature.toUpperCase()
}
getParamsString (params) {
return Object.keys(params)
.sort()
.filter(item => typeof params[item] !== "object")
.map(item => `${item}=${params[item]}`)
.join('&')
}
}
const requestAuthSecret = "testSecret"
const nonce = Math.random().toString(36).substring(2)
const timestamp = Date.now()
const params = {
foo: 1,
bar: 2,
foo_bar: 3,
foobar: 4
}
const sign = new Sign(requestAuthSecret)
const signature = sign.getSignature(params, nonce, timestamp)
console.log("nonce: ", nonce)
console.log("timestamp: ", timestamp)
console.log("signature: ", signature)
<?php
class Sign {
private $requestAuthSecret;
public function __construct ($requestAuthSecret) {
$this->requestAuthSecret = $requestAuthSecret;
}
public function getSignature ($params, $nonce, $timestamp) {
$paramsStr = $this->getParamsString($params);
$signature = hash_hmac('sha256', ((string)$timestamp . $paramsStr), ($this->requestAuthSecret . $nonce));
return strtoupper($signature);
}
private function getParamsString ($params) {
ksort($params);
$paramsStr = [];
foreach($params as $key=>$value){
if (gettype($value) == "array" || gettype($value) == "object") {
continue;
}
array_push($paramsStr, $key . '=' . $value);
}
return join('&', $paramsStr);
}
}
$requestAuthSecret = "testSecret";
$nonce = sprintf("%d", rand());
$timestamp = time() * 1000;
$params = [
"foo" => 1,
"bar" => 2,
"foobar" => 4,
"foo_bar" => 3,
];
$sign = new Sign($requestAuthSecret);
$signature = $sign->getSignature($params, $nonce, $timestamp);
print_r("nonce: " . $nonce . PHP_EOL);
print_r("timestamp: " . $timestamp . PHP_EOL);
print_r("signature: " . $signature);
import hmac
import hashlib
import time
class Sign:
def __init__(self, requestAuthSecret):
self.requestAuthSecret = requestAuthSecret
def get_signature (self, params, nonce, timestamp):
params_str = self.get_params_string(params)
signature = hmac.new(bytes("%s%s" % (self.requestAuthSecret, nonce), 'utf-8'), bytes("%s%s" % (timestamp, params_str), 'utf-8'), digestmod = hashlib.sha256).hexdigest().upper()
return signature
def get_params_string(self, params):
params_str = []
for k in sorted(params):
if isinstance(params[k], (list, dict)):
continue
params_str.append("%s=%s" % (k, params[k]))
return "&".join(params_str)
if __name__ == "__main__":
requestAuthSecret = "testSecret"
nonce = "xxxxxxx"
timestamp = int(round(time.time() * 1000))
params = {
"foo": 1,
"bar": 2,
"foobar": 4,
"foo_bar": 3,
}
sign = Sign(requestAuthSecret)
signature = sign.get_signature(params, nonce, timestamp)
print(nonce, timestamp, signature)
package main
import (
"crypto/hmac"
"crypto/sha256"
"encoding/hex"
"fmt"
"sort"
"strconv"
"strings"
"time"
)
type Sign struct {
requestAuthSecret string
}
func (sign Sign) getSignature(params map[string]string, nonce string, timestamp int64) string {
paramsStr := sign.getParamsString(params)
mac := hmac.New(sha256.New, []byte(sign.requestAuthSecret+nonce))
mac.Write([]byte(strconv.Itoa(int(timestamp)) + paramsStr))
hexSignature := mac.Sum(nil)
signature := hex.EncodeToString(hexSignature)
return strings.ToUpper(signature)
}
func (sign Sign) getParamsString(params map[string]string) string {
keys := make([]string, 0, len(params))
for k := range params {
keys = append(keys, k)
}
sort.Strings(keys)
var paramsStr string = ""
i := 0
for _, k := range keys {
v := params[k]
if i != 0 {
paramsStr += "&"
}
paramsStr += k
paramsStr += "="
paramsStr += v
i++
}
return paramsStr
}
func main() {
requestAuthSecret := "testSecret"
nonce := "xxxxxxx"
timestamp := time.Now().UnixMilli()
params := map[string]string{
"foo": "1",
"bar": "2",
"foo_bar": "3",
"foobar": "4",
}
sign := Sign{
requestAuthSecret: requestAuthSecret,
}
signature := sign.getSignature(params, nonce, timestamp)
result := fmt.Sprintf("nonce: %s, timestamp: %d, signature: %s", nonce, timestamp, signature)
fmt.Println(result)
}
import java.util.HashMap;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.util.Arrays;
import java.util.Map;
public class Sign {
static String requestAuthSecret = "testSecret";
public static void main(String[] args) {
String nonce = "xxxxxx";
long timestamp = System.currentTimeMillis();
Map<String, String> params = new HashMap<String, String>();
params.put("foo", "1");
params.put("bar", "2");
params.put("foo_bar", "4");
params.put("foobar", "3");
String signature = getSignature(params, nonce, timestamp);
System.out.println("nonce: " + nonce);
System.out.println("timestamp: " + timestamp);
System.out.println("signature: " + signature);
}
public static String getSignature (Map<String, String> params, String nonce, long timestamp) {
String paramsStr = getParamsString(params);
String algorithm = "HmacSHA256";
Mac hmacSha256;
String digestHexString = null;
try {
hmacSha256 = Mac.getInstance(algorithm);
String key = new StringBuilder().append(requestAuthSecret).append(nonce).toString();
String message = new StringBuilder().append(Long.toString(timestamp)).append(paramsStr).toString();
byte[] keyBytes = key.getBytes("utf-8");
byte[] messageBytes = message.getBytes("utf-8");
hmacSha256.init(new SecretKeySpec(keyBytes, 0, keyBytes.length, algorithm));
byte[] digestBytes = hmacSha256.doFinal(messageBytes);
digestHexString = byteArrayToHexString(digestBytes);
} catch (Exception e) {
System.out.println("[ERROR] not supposed to happen: " + e.getMessage());
}
return digestHexString.toUpperCase();
}
private static String getParamsString (Map<String, String> params) {
String[] keys = params.keySet().toArray(new String[0]);
Arrays.sort(keys);
StringBuilder sb = new StringBuilder();
for (int i = 0; i < keys.length; i ++) {
String key = keys[i];
if (i != 0) {
sb.append("&");
}
sb.append(key).append("=").append(params.get(key));
}
return sb.toString();
}
private static String byteArrayToHexString(byte[] b) {
StringBuilder hs = new StringBuilder();
String stmp;
for (int n = 0; b!=null && n < b.length; n++) {
stmp = Integer.toHexString(b[n] & 0XFF);
if (stmp.length() == 1)
hs.append('0');
hs.append(stmp);
}
return hs.toString();
}
}