English
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 // 分模块存放的云对象方法
uni-id-co
所有api返回值均满足uniCloud响应体规范
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
自uni-id-pages@1.0.29
版本起支持URL化 什么是URL化
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 | 是 | 密码 |
captcha | string | 否(此操作错误3次以上为必填) | 图形验证码 |
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 | 否(此操作错误3次以上为必填) | 图形验证码 |
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
及以上版本会使用uni-open-bridge-common保存session_key
(微信小程序登录)、access_token
(微信公众号登录、微信App登录)这些信息,但是为了兼容旧版逻辑仍在用户表存储了一份副本。详细说明参考:自动保存用户sessionKey、accessToken等信息uni-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
及以上版本会使用uni-open-bridge-common保存session_key(QQ小程序登录)、access_token(QQ App登录)这些信息,但是为了兼容旧版逻辑仍在用户表存储了一份副本。详细说明参考:自动保存用户sessionKey、accessToken等信息Note 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 | 是 | 短信验证码 |
captcha | string | 否(此操作错误3次以上为必填) | 图形验证码 |
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 | 是 | 手机验证码 |
captcha | string | 否(此操作错误3次以上为必填) | 图形验证码 |
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 | 是 | 密码 |
captcha | string | 否(此操作错误3次以上为必填) | 图形验证码 |
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 | 是 | 密码 |
captcha | string | 否(此操作错误3次以上为必填) | 图形验证码 |
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 | 是 | 图形验证码使用场景,务必确保使用验证码的场景和生成验证码时传的场景参数相匹配,否则会校验不通过,参考:图形验证码场景 |
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 | 是 | 图形验证码使用场景,参考:图形验证码场景 |
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 | 是 | 图形验证码 |
scene | string | 是 | 短信验证码使用场景,务必确保使用验证码的场景和发送验证码时传的场景参数相匹配,否则会校验不通过,参考:短信验证码使用场景 |
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 |
此接口用于微信小程序端安全网络的握手,安全网络相关文档请参考:安全网络
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 | 否 | 用户标签 |
status | number | 否 | 用户状态,参考:用户状态 |
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>'
})
}
}
服务端uni-id
的密钥信息统一在uni-config-center
中配置,路径:uni_modules/uni-config-center/uniCloud/cloudfunctions/common/uni-config-center/uni-id/config.json
以下简称:uni-id配置文件
,完整的配置信息详情查看
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
的密钥信息统一在uni-config-center
中配置,路径:uniCloud/cloudfunctions/common/uni-config-center/uni-id/config.json
,完整的配置信息详情查看登录的流程为:
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();
}
}