提交 4762d3c6 编写于 作者: Anne_LXM's avatar Anne_LXM

更新 依赖的uni-id-pages的版本为1.1.22

上级 4cf41359
## 1.1.22(2024-09-13)
- 注册登录时去除字符串两端的空白字符
- 删除static目录下重复资源
## 1.1.21(2024-08-02) ## 1.1.21(2024-08-02)
- uni-id-co 修复联登更新用户信息接口存在手机号或者邮箱时没有设置认证状态 - uni-id-co 修复联登更新用户信息接口存在手机号或者邮箱时没有设置认证状态
## 1.1.20(2024-04-28) ## 1.1.20(2024-04-28)
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
<view> <view>
<uni-captcha :focus="focusCaptchaInput" ref="captcha" scene="send-sms-code" v-model="captcha" /> <uni-captcha :focus="focusCaptchaInput" ref="captcha" scene="send-sms-code" v-model="captcha" />
<view class="box"> <view class="box">
<uni-easyinput :focus="focusSmsCodeInput" @blur="focusSmsCodeInput = false" type="number" class="input-box" :inputBorder="false" v-model="modelValue" maxlength="6" :clearable="false" <uni-easyinput :focus="focusSmsCodeInput" @blur="focusSmsCodeInput = false" type="number" class="input-box" :inputBorder="false" v-model="modelValue" maxlength="6" :clearable="false" trim="both"
placeholder="请输入短信验证码"> placeholder="请输入短信验证码">
</uni-easyinput> </uni-easyinput>
<view class="short-code-btn" hover-class="hover" @click="start"> <view class="short-code-btn" hover-class="hover" @click="start">
......
{ {
"id": "uni-id-pages", "id": "uni-id-pages",
"displayName": "uni-id-pages", "displayName": "uni-id-pages",
"version": "1.1.21", "version": "1.1.22",
"description": "云端一体简单、统一、可扩展的用户中心页面模版", "description": "云端一体简单、统一、可扩展的用户中心页面模版",
"keywords": [ "keywords": [
"用户管理", "用户管理",
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
], ],
"repository": "https://gitcode.net/dcloud/hello_uni-id-pages", "repository": "https://gitcode.net/dcloud/hello_uni-id-pages",
"engines": { "engines": {
"HBuilderX": "^3.4.17" "HBuilderX": "^4.15"
}, },
"dcloudext": { "dcloudext": {
"sale": { "sale": {
......
...@@ -21,7 +21,7 @@ ...@@ -21,7 +21,7 @@
<text class="tip">未注册的账号验证通过后将自动注册</text> <text class="tip">未注册的账号验证通过后将自动注册</text>
<view class="phone-box"> <view class="phone-box">
<view @click="chooseArea" class="area">+86</view> <view @click="chooseArea" class="area">+86</view>
<uni-easyinput :focus="focusPhone" @blur="focusPhone = false" class="input-box" type="number" <uni-easyinput trim="both" :focus="focusPhone" @blur="focusPhone = false" class="input-box" type="number"
:inputBorder="false" v-model="phone" maxlength="11" placeholder="请输入手机号" /> :inputBorder="false" v-model="phone" maxlength="11" placeholder="请输入手机号" />
</view> </view>
<uni-id-pages-agreements scope="register" ref="agreements"></uni-id-pages-agreements> <uni-id-pages-agreements scope="register" ref="agreements"></uni-id-pages-agreements>
......
...@@ -9,11 +9,11 @@ ...@@ -9,11 +9,11 @@
<uni-forms> <uni-forms>
<uni-forms-item name="username"> <uni-forms-item name="username">
<uni-easyinput :focus="focusUsername" @blur="focusUsername = false" class="input-box" <uni-easyinput :focus="focusUsername" @blur="focusUsername = false" class="input-box"
:inputBorder="false" v-model="username" placeholder="请输入手机号/用户名/邮箱" /> :inputBorder="false" v-model="username" placeholder="请输入手机号/用户名/邮箱" trim="all" />
</uni-forms-item> </uni-forms-item>
<uni-forms-item name="password"> <uni-forms-item name="password">
<uni-easyinput :focus="focusPassword" @blur="focusPassword = false" class="input-box" clearable <uni-easyinput :focus="focusPassword" @blur="focusPassword = false" class="input-box" clearable
type="password" :inputBorder="false" v-model="password" placeholder="请输入密码" /> type="password" :inputBorder="false" v-model="password" placeholder="请输入密码" trim="all" />
</uni-forms-item> </uni-forms-item>
</uni-forms> </uni-forms>
<uni-captcha v-if="needCaptcha" focus ref="captcha" scene="login-by-pwd" v-model="captcha" /> <uni-captcha v-if="needCaptcha" focus ref="captcha" scene="login-by-pwd" v-model="captcha" />
......
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
</match-media> </match-media>
<uni-forms ref="form" :value="formData" err-show-type="toast"> <uni-forms ref="form" :value="formData" err-show-type="toast">
<uni-forms-item name="email"> <uni-forms-item name="email">
<uni-easyinput :focus="focusEmail" @blur="focusEmail = false" class="input-box" :disabled="lock" :inputBorder="false" <uni-easyinput :focus="focusEmail" @blur="focusEmail = false" class="input-box" :disabled="lock" :inputBorder="false" trim="both"
v-model="formData.email" placeholder="请输入邮箱"> v-model="formData.email" placeholder="请输入邮箱">
</uni-easyinput> </uni-easyinput>
</uni-forms-item> </uni-forms-item>
...@@ -19,11 +19,11 @@ ...@@ -19,11 +19,11 @@
</uni-id-pages-email-form> </uni-id-pages-email-form>
</uni-forms-item> </uni-forms-item>
<uni-forms-item name="password"> <uni-forms-item name="password">
<uni-easyinput :focus="focusPassword" @blur="focusPassword = false" class="input-box" type="password" :inputBorder="false" v-model="formData.password" <uni-easyinput :focus="focusPassword" @blur="focusPassword = false" class="input-box" type="password" :inputBorder="false" v-model="formData.password" trim="both"
placeholder="请输入新密码"></uni-easyinput> placeholder="请输入新密码"></uni-easyinput>
</uni-forms-item> </uni-forms-item>
<uni-forms-item name="password2"> <uni-forms-item name="password2">
<uni-easyinput :focus="focusPassword2" @blur="focusPassword2 = false" class="input-box" type="password" :inputBorder="false" v-model="formData.password2" <uni-easyinput :focus="focusPassword2" @blur="focusPassword2 = false" class="input-box" type="password" :inputBorder="false" v-model="formData.password2" trim="both"
placeholder="请再次输入新密码"></uni-easyinput> placeholder="请再次输入新密码"></uni-easyinput>
</uni-forms-item> </uni-forms-item>
<button class="uni-btn send-btn-box" type="primary" @click="submit">提交</button> <button class="uni-btn send-btn-box" type="primary" @click="submit">提交</button>
......
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
</match-media> </match-media>
<uni-forms ref="form" :value="formData" err-show-type="toast"> <uni-forms ref="form" :value="formData" err-show-type="toast">
<uni-forms-item name="phone"> <uni-forms-item name="phone">
<uni-easyinput :focus="focusPhone" @blur="focusPhone = false" class="input-box" :disabled="lock" type="number" :inputBorder="false" <uni-easyinput :focus="focusPhone" @blur="focusPhone = false" class="input-box" :disabled="lock" type="number" :inputBorder="false" trim="both"
v-model="formData.phone" maxlength="11" placeholder="请输入手机号"> v-model="formData.phone" maxlength="11" placeholder="请输入手机号">
</uni-easyinput> </uni-easyinput>
</uni-forms-item> </uni-forms-item>
...@@ -19,11 +19,11 @@ ...@@ -19,11 +19,11 @@
</uni-id-pages-sms-form> </uni-id-pages-sms-form>
</uni-forms-item> </uni-forms-item>
<uni-forms-item name="password"> <uni-forms-item name="password">
<uni-easyinput :focus="focusPassword" @blur="focusPassword = false" class="input-box" type="password" :inputBorder="false" v-model="formData.password" <uni-easyinput :focus="focusPassword" @blur="focusPassword = false" class="input-box" type="password" :inputBorder="false" v-model="formData.password" trim="both"
placeholder="请输入新密码"></uni-easyinput> placeholder="请输入新密码"></uni-easyinput>
</uni-forms-item> </uni-forms-item>
<uni-forms-item name="password2"> <uni-forms-item name="password2">
<uni-easyinput :focus="focusPassword2" @blur="focusPassword2 = false" class="input-box" type="password" :inputBorder="false" v-model="formData.password2" <uni-easyinput :focus="focusPassword2" @blur="focusPassword2 = false" class="input-box" type="password" :inputBorder="false" v-model="formData.password2" trim="both"
placeholder="请再次输入新密码"></uni-easyinput> placeholder="请再次输入新密码"></uni-easyinput>
</uni-forms-item> </uni-forms-item>
<button class="uni-btn send-btn-box" type="primary" @click="submit">提交</button> <button class="uni-btn send-btn-box" type="primary" @click="submit">提交</button>
......
...@@ -20,6 +20,8 @@ ...@@ -20,6 +20,8 @@
"cloudfunction-config": { "cloudfunction-config": {
"keepRunningAfterReturn": false "keepRunningAfterReturn": false
}, },
"origin-plugin-dev-name": "uni-id-pages",
"origin-plugin-version": "1.1.22",
"plugin-dev-name": "uni-id-pages", "plugin-dev-name": "uni-id-pages",
"plugin-version": "1.1.21" "plugin-version": "1.1.22"
} }
## 1.2.1(2024-09-13)
- 修复 微信小程序平台 当微信的服务器返回`encrypt_key`的过期时间`expire_in``0`时特殊处理为`1`天,否者可能无法验证客户端请求携带的版本
## 1.2.0(2023-04-27) ## 1.2.0(2023-04-27)
- 优化 微信小程序平台 使用微信新增 API getStableAccessToken 获取 access_token, access_token 有效期内重复调用该接口不会更新 access_token, [详情](https://developers.weixin.qq.com/miniprogram/dev/OpenApiDoc/mp-access-token/getStableAccessToken.html) - 重要 微信小程序平台 使用微信新增 API getStableAccessToken 获取 access_token, access_token 有效期内重复调用该接口不会更新 access_token, [详情](https://developers.weixin.qq.com/miniprogram/dev/OpenApiDoc/mp-access-token/getStableAccessToken.html)
## 1.1.5(2023-03-27) ## 1.1.5(2023-03-27)
- 修复 微信小程序平台 某些情况下 encrypt_key 插入错误的问题 - 修复 微信小程序平台 某些情况下 encrypt_key 插入错误的问题
## 1.1.4(2023-03-13) ## 1.1.4(2023-03-13)
......
{ {
"id": "uni-open-bridge-common", "id": "uni-open-bridge-common",
"displayName": "uni-open-bridge-common", "displayName": "uni-open-bridge-common",
"version": "1.2.0", "version": "1.2.1",
"description": "统一接管微信等三方平台认证凭据", "description": "统一接管微信等三方平台认证凭据",
"keywords": [ "keywords": [
"uni-open-bridge-common",
"access_token", "access_token",
"session_key", "session_key",
"ticket" "ticket"
...@@ -39,7 +38,8 @@ ...@@ -39,7 +38,8 @@
"platforms": { "platforms": {
"cloud": { "cloud": {
"tcb": "y", "tcb": "y",
"aliyun": "y" "aliyun": "y",
"alipay": "n"
}, },
"client": { "client": {
"Vue": { "Vue": {
......
# uni-open-bridge-common # uni-open-bridge-common
`uni-open-bridge-common` 是统一接管微信等三方平台认证凭据(包括但不限于`access_token``session_key``encrypt_key``ticket`)的开源库。 `uni-open-bridge-common` 是统一接管微信等三方平台认证凭据(包括但不限于`access_token``session_key``encrypt_key``ticket`)的开源库。
文档链接 [https://uniapp.dcloud.net.cn/uniCloud/uni-open-bridge#common](https://uniapp.dcloud.net.cn/uniCloud/uni-open-bridge#common) 文档链接 [https://uniapp.dcloud.net.cn/uniCloud/uni-open-bridge#common](https://uniapp.dcloud.net.cn/uniCloud/uni-open-bridge#common)
'use strict'; 'use strict';
class BridgeError extends Error { class BridgeError extends Error {
...@@ -20,7 +20,7 @@ class BridgeError extends Error { ...@@ -20,7 +20,7 @@ class BridgeError extends Error {
return this.message return this.message
} }
} }
module.exports = { module.exports = {
BridgeError BridgeError
} }
'use strict'; 'use strict';
const { const {
ProviderType ProviderType
} = require('./consts.js') } = require('./consts.js')
const configCenter = require('uni-config-center') const configCenter = require('uni-config-center')
// 多维数据为兼容uni-id以前版本配置 // 多维数据为兼容uni-id以前版本配置
const OauthConfig = { const OauthConfig = {
'weixin-app': [ 'weixin-app': [
['app', 'oauth', 'weixin'], ['app', 'oauth', 'weixin'],
['app-plus', 'oauth', 'weixin'] ['app-plus', 'oauth', 'weixin']
], ],
'weixin-mp': [ 'weixin-mp': [
['mp-weixin', 'oauth', 'weixin'] ['mp-weixin', 'oauth', 'weixin']
], ],
'weixin-h5': [ 'weixin-h5': [
['web', 'oauth', 'weixin-h5'], ['web', 'oauth', 'weixin-h5'],
['h5-weixin', 'oauth', 'weixin'], ['h5-weixin', 'oauth', 'weixin'],
['h5', 'oauth', 'weixin'] ['h5', 'oauth', 'weixin']
], ],
'weixin-web': [ 'weixin-web': [
['web', 'oauth', 'weixin-web'] ['web', 'oauth', 'weixin-web']
], ],
'qq-app': [ 'qq-app': [
['app', 'oauth', 'qq'], ['app', 'oauth', 'qq'],
['app-plus', 'oauth', 'qq'] ['app-plus', 'oauth', 'qq']
], ],
'qq-mp': [ 'qq-mp': [
['mp-qq', 'oauth', 'qq'] ['mp-qq', 'oauth', 'qq']
] ]
} }
const Support_Platforms = [ const Support_Platforms = [
ProviderType.WEIXIN_MP, ProviderType.WEIXIN_MP,
ProviderType.WEIXIN_H5, ProviderType.WEIXIN_H5,
ProviderType.WEIXIN_APP, ProviderType.WEIXIN_APP,
ProviderType.WEIXIN_WEB, ProviderType.WEIXIN_WEB,
ProviderType.QQ_MP, ProviderType.QQ_MP,
ProviderType.QQ_APP ProviderType.QQ_APP
] ]
class ConfigBase { class ConfigBase {
constructor() { constructor() {
const uniIdConfigCenter = configCenter({ const uniIdConfigCenter = configCenter({
pluginId: 'uni-id' pluginId: 'uni-id'
}) })
this._uniIdConfig = uniIdConfigCenter.config() this._uniIdConfig = uniIdConfigCenter.config()
} }
getAppConfig(appid) { getAppConfig(appid) {
if (Array.isArray(this._uniIdConfig)) { if (Array.isArray(this._uniIdConfig)) {
return this._uniIdConfig.find((item) => { return this._uniIdConfig.find((item) => {
return (item.dcloudAppid === appid) return (item.dcloudAppid === appid)
}) })
} }
return this._uniIdConfig return this._uniIdConfig
} }
} }
class AppConfig extends ConfigBase { class AppConfig extends ConfigBase {
constructor() { constructor() {
super() super()
} }
get(appid, platform) { get(appid, platform) {
if (!this.isSupport(platform)) { if (!this.isSupport(platform)) {
return null return null
} }
let appConfig = this.getAppConfig(appid) let appConfig = this.getAppConfig(appid)
if (!appConfig) { if (!appConfig) {
return null return null
} }
return this.getOauthConfig(appConfig, platform) return this.getOauthConfig(appConfig, platform)
} }
isSupport(platformName) { isSupport(platformName) {
return (Support_Platforms.indexOf(platformName) >= 0) return (Support_Platforms.indexOf(platformName) >= 0)
} }
getOauthConfig(appConfig, platformName) { getOauthConfig(appConfig, platformName) {
let treePath = OauthConfig[platformName] let treePath = OauthConfig[platformName]
let node = this.findNode(appConfig, treePath) let node = this.findNode(appConfig, treePath)
if (node && node.appid && node.appsecret) { if (node && node.appid && node.appsecret) {
return { return {
appid: node.appid, appid: node.appid,
secret: node.appsecret secret: node.appsecret
} }
} }
return null return null
} }
findNode(treeNode, arrayPath) { findNode(treeNode, arrayPath) {
let node = treeNode let node = treeNode
for (let treePath of arrayPath) { for (let treePath of arrayPath) {
for (let name of treePath) { for (let name of treePath) {
const currentNode = node[name] const currentNode = node[name]
if (currentNode) { if (currentNode) {
node = currentNode node = currentNode
} else { } else {
node = null node = null
break break
} }
} }
if (node === null) { if (node === null) {
node = treeNode node = treeNode
} else { } else {
break break
} }
} }
return node return node
} }
} }
module.exports = { module.exports = {
AppConfig AppConfig
}; };
\ No newline at end of file
'use strict'; 'use strict';
const TAG = "UNI_OPEN_BRIDGE" const TAG = "UNI_OPEN_BRIDGE"
const HTTP_STATUS = { const HTTP_STATUS = {
SUCCESS: 200 SUCCESS: 200
} }
const ProviderType = { const ProviderType = {
WEIXIN_MP: 'weixin-mp', WEIXIN_MP: 'weixin-mp',
WEIXIN_H5: 'weixin-h5', WEIXIN_H5: 'weixin-h5',
WEIXIN_APP: 'weixin-app', WEIXIN_APP: 'weixin-app',
WEIXIN_WEB: 'weixin-web', WEIXIN_WEB: 'weixin-web',
QQ_MP: 'qq-mp', QQ_MP: 'qq-mp',
QQ_APP: 'qq-app' QQ_APP: 'qq-app'
} }
// old // old
const PlatformType = ProviderType const PlatformType = ProviderType
const ErrorCodeType = { const ErrorCodeType = {
SYSTEM_ERROR: TAG + "_SYSTEM_ERROR" SYSTEM_ERROR: TAG + "_SYSTEM_ERROR"
} }
module.exports = { module.exports = {
HTTP_STATUS, HTTP_STATUS,
ProviderType, ProviderType,
PlatformType, PlatformType,
ErrorCodeType ErrorCodeType
} }
'use strict'; 'use strict';
const { const {
PlatformType, PlatformType,
ProviderType, ProviderType,
ErrorCodeType ErrorCodeType
} = require('./consts.js') } = require('./consts.js')
const { const {
AppConfig AppConfig
} = require('./config.js') } = require('./config.js')
const { const {
Storage Storage
} = require('./storage.js') } = require('./storage.js')
const { const {
BridgeError BridgeError
} = require('./bridge-error.js') } = require('./bridge-error.js')
const { const {
WeixinServer WeixinServer
} = require('./weixin-server.js') } = require('./weixin-server.js')
const appConfig = new AppConfig() const appConfig = new AppConfig()
class AccessToken extends Storage { class AccessToken extends Storage {
constructor() { constructor() {
super('access-token', ['provider', 'appid']) super('access-token', ['provider', 'appid'])
} }
async update(key) { async update(key) {
super.update(key) super.update(key)
const result = await this.getByWeixinServer(key) const result = await this.getByWeixinServer(key)
return this.set(key, result.value, result.duration) return this.set(key, result.value, result.duration)
} }
async fallback(key) { async fallback(key) {
return this.getByWeixinServer(key) return this.getByWeixinServer(key)
} }
async getByWeixinServer(key) { async getByWeixinServer(key) {
const oauthConfig = appConfig.get(key.dcloudAppid, key.provider) const oauthConfig = appConfig.get(key.dcloudAppid, key.provider)
let methodName let methodName
if (key.provider === ProviderType.WEIXIN_MP) { if (key.provider === ProviderType.WEIXIN_MP) {
methodName = 'GetMPAccessTokenData' methodName = 'GetMPAccessTokenData'
} else if (key.provider === ProviderType.WEIXIN_H5) { } else if (key.provider === ProviderType.WEIXIN_H5) {
methodName = 'GetH5AccessTokenData' methodName = 'GetH5AccessTokenData'
} else { } else {
throw new BridgeError(ErrorCodeType.SYSTEM_ERROR, "provider invalid") throw new BridgeError(ErrorCodeType.SYSTEM_ERROR, "provider invalid")
} }
const responseData = await WeixinServer[methodName](oauthConfig) const responseData = await WeixinServer[methodName](oauthConfig)
const duration = responseData.expires_in || (60 * 60 * 2) const duration = responseData.expires_in || (60 * 60 * 2)
delete responseData.expires_in delete responseData.expires_in
return { return {
value: responseData, value: responseData,
duration duration
} }
} }
} }
class UserAccessToken extends Storage { class UserAccessToken extends Storage {
constructor() { constructor() {
super('user-access-token', ['provider', 'appid', 'openid']) super('user-access-token', ['provider', 'appid', 'openid'])
} }
} }
class SessionKey extends Storage { class SessionKey extends Storage {
constructor() { constructor() {
super('session-key', ['provider', 'appid', 'openid']) super('session-key', ['provider', 'appid', 'openid'])
} }
} }
class Encryptkey extends Storage { class Encryptkey extends Storage {
constructor() { constructor() {
super('encrypt-key', ['provider', 'appid', 'openid']) super('encrypt-key', ['provider', 'appid', 'openid'])
} }
async update(key) { async update(key) {
super.update(key) super.update(key)
const result = await this.getByWeixinServer(key) const result = await this.getByWeixinServer(key)
return this.set(key, result.value, result.duration) return this.set(key, result.value, result.duration)
} }
getKeyString(key) { getKeyString(key) {
return `${super.getKeyString(key)}-${key.version}` return `${super.getKeyString(key)}-${key.version}`
} }
getExpiresIn(value) { getExpiresIn(value) {
if (value <= 0) { if (value <= 0) {
return 60 return 60
} }
return value return value
} }
async fallback(key) { async fallback(key) {
return this.getByWeixinServer(key) return this.getByWeixinServer(key)
} }
async getByWeixinServer(key) { async getByWeixinServer(key) {
const accessToken = await Factory.Get(AccessToken, key) const accessToken = await Factory.Get(AccessToken, key)
const userSession = await Factory.Get(SessionKey, key) const userSession = await Factory.Get(SessionKey, key)
const responseData = await WeixinServer.GetUserEncryptKeyData({ const responseData = await WeixinServer.GetUserEncryptKeyData({
openid: key.openid, openid: key.openid,
access_token: accessToken.access_token, access_token: accessToken.access_token,
session_key: userSession.session_key session_key: userSession.session_key
}) })
const keyInfo = responseData.key_info_list.find((item) => { const keyInfo = responseData.key_info_list.find((item) => {
return item.version === key.version return item.version === key.version
}) })
if (!keyInfo) { if (!keyInfo) {
throw new BridgeError(ErrorCodeType.SYSTEM_ERROR, 'key version invalid') throw new BridgeError(ErrorCodeType.SYSTEM_ERROR, 'key version invalid')
} }
const value = { const value = {
encrypt_key: keyInfo.encrypt_key, encrypt_key: keyInfo.encrypt_key,
iv: keyInfo.iv iv: keyInfo.iv
} }
return { return {
value, value,
duration: keyInfo.expire_in duration: keyInfo.expire_in || (24*60*60)
} }
} }
} }
class Ticket extends Storage { class Ticket extends Storage {
constructor() { constructor() {
super('ticket', ['provider', 'appid']) super('ticket', ['provider', 'appid'])
} }
async update(key) { async update(key) {
super.update(key) super.update(key)
const result = await this.getByWeixinServer(key) const result = await this.getByWeixinServer(key)
return this.set(key, result.value, result.duration) return this.set(key, result.value, result.duration)
} }
async fallback(key) { async fallback(key) {
return this.getByWeixinServer(key) return this.getByWeixinServer(key)
} }
async getByWeixinServer(key) { async getByWeixinServer(key) {
const accessToken = await Factory.Get(AccessToken, { const accessToken = await Factory.Get(AccessToken, {
dcloudAppid: key.dcloudAppid, dcloudAppid: key.dcloudAppid,
provider: ProviderType.WEIXIN_H5 provider: ProviderType.WEIXIN_H5
}) })
const responseData = await WeixinServer.GetH5TicketData(accessToken) const responseData = await WeixinServer.GetH5TicketData(accessToken)
const duration = responseData.expires_in || (60 * 60 * 2) const duration = responseData.expires_in || (60 * 60 * 2)
delete responseData.expires_in delete responseData.expires_in
delete responseData.errcode delete responseData.errcode
delete responseData.errmsg delete responseData.errmsg
return { return {
value: responseData, value: responseData,
duration duration
} }
} }
} }
const Factory = { const Factory = {
async Get(T, key, fallback) { async Get(T, key, fallback) {
Factory.FixOldKey(key) Factory.FixOldKey(key)
return Factory.MakeUnique(T).get(key, fallback) return Factory.MakeUnique(T).get(key, fallback)
}, },
async Set(T, key, value, expiresIn) { async Set(T, key, value, expiresIn) {
Factory.FixOldKey(key) Factory.FixOldKey(key)
return Factory.MakeUnique(T).set(key, value, expiresIn) return Factory.MakeUnique(T).set(key, value, expiresIn)
}, },
async Remove(T, key) { async Remove(T, key) {
Factory.FixOldKey(key) Factory.FixOldKey(key)
return Factory.MakeUnique(T).remove(key) return Factory.MakeUnique(T).remove(key)
}, },
async Update(T, key) { async Update(T, key) {
Factory.FixOldKey(key) Factory.FixOldKey(key)
return Factory.MakeUnique(T).update(key) return Factory.MakeUnique(T).update(key)
}, },
FixOldKey(key) { FixOldKey(key) {
if (!key.provider) { if (!key.provider) {
key.provider = key.platform key.provider = key.platform
} }
const configData = appConfig.get(key.dcloudAppid, key.provider) const configData = appConfig.get(key.dcloudAppid, key.provider)
if (!configData) { if (!configData) {
throw new BridgeError(ErrorCodeType.SYSTEM_ERROR, 'appid or provider invalid') throw new BridgeError(ErrorCodeType.SYSTEM_ERROR, 'appid or provider invalid')
} }
key.appid = configData.appid key.appid = configData.appid
}, },
MakeUnique(T) { MakeUnique(T) {
return new T() return new T()
} }
} }
// exports // exports
async function getAccessToken(key, fallback) { async function getAccessToken(key, fallback) {
return Factory.Get(AccessToken, key, fallback) return Factory.Get(AccessToken, key, fallback)
} }
async function setAccessToken(key, value, expiresIn) { async function setAccessToken(key, value, expiresIn) {
return Factory.Set(AccessToken, key, value, expiresIn) return Factory.Set(AccessToken, key, value, expiresIn)
} }
async function removeAccessToken(key) { async function removeAccessToken(key) {
return Factory.Remove(AccessToken, key) return Factory.Remove(AccessToken, key)
} }
async function updateAccessToken(key) { async function updateAccessToken(key) {
return Factory.Update(AccessToken, key) return Factory.Update(AccessToken, key)
} }
async function getUserAccessToken(key, fallback) { async function getUserAccessToken(key, fallback) {
return Factory.Get(UserAccessToken, key, fallback) return Factory.Get(UserAccessToken, key, fallback)
} }
async function setUserAccessToken(key, value, expiresIn) { async function setUserAccessToken(key, value, expiresIn) {
return Factory.Set(UserAccessToken, key, value, expiresIn) return Factory.Set(UserAccessToken, key, value, expiresIn)
} }
async function removeUserAccessToken(key) { async function removeUserAccessToken(key) {
return Factory.Remove(UserAccessToken, key) return Factory.Remove(UserAccessToken, key)
} }
async function getSessionKey(key, fallback) { async function getSessionKey(key, fallback) {
return Factory.Get(SessionKey, key, fallback) return Factory.Get(SessionKey, key, fallback)
} }
async function setSessionKey(key, value, expiresIn) { async function setSessionKey(key, value, expiresIn) {
return Factory.Set(SessionKey, key, value, expiresIn) return Factory.Set(SessionKey, key, value, expiresIn)
} }
async function removeSessionKey(key) { async function removeSessionKey(key) {
return Factory.Remove(SessionKey, key) return Factory.Remove(SessionKey, key)
} }
async function getEncryptKey(key, fallback) { async function getEncryptKey(key, fallback) {
return Factory.Get(Encryptkey, key, fallback) return Factory.Get(Encryptkey, key, fallback)
} }
async function setEncryptKey(key, value, expiresIn) { async function setEncryptKey(key, value, expiresIn) {
return Factory.Set(Encryptkey, key, value, expiresIn) return Factory.Set(Encryptkey, key, value, expiresIn)
} }
async function removeEncryptKey(key) { async function removeEncryptKey(key) {
return Factory.Remove(Encryptkey, key) return Factory.Remove(Encryptkey, key)
} }
async function updateEncryptKey(key) { async function updateEncryptKey(key) {
return Factory.Update(Encryptkey, key) return Factory.Update(Encryptkey, key)
} }
async function getTicket(key, fallback) { async function getTicket(key, fallback) {
return Factory.Get(Ticket, key, fallback) return Factory.Get(Ticket, key, fallback)
} }
async function setTicket(key, value, expiresIn) { async function setTicket(key, value, expiresIn) {
return Factory.Set(Ticket, key, value, expiresIn) return Factory.Set(Ticket, key, value, expiresIn)
} }
async function removeTicket(key) { async function removeTicket(key) {
return Factory.Remove(Ticket, key) return Factory.Remove(Ticket, key)
} }
async function updateTicket(key) { async function updateTicket(key) {
return Factory.Update(Ticket, key) return Factory.Update(Ticket, key)
} }
module.exports = { module.exports = {
getAccessToken, getAccessToken,
setAccessToken, setAccessToken,
removeAccessToken, removeAccessToken,
updateAccessToken, updateAccessToken,
getUserAccessToken, getUserAccessToken,
setUserAccessToken, setUserAccessToken,
removeUserAccessToken, removeUserAccessToken,
getSessionKey, getSessionKey,
setSessionKey, setSessionKey,
removeSessionKey, removeSessionKey,
getEncryptKey, getEncryptKey,
setEncryptKey, setEncryptKey,
removeEncryptKey, removeEncryptKey,
updateEncryptKey, updateEncryptKey,
getTicket, getTicket,
setTicket, setTicket,
removeTicket, removeTicket,
updateTicket, updateTicket,
ProviderType, ProviderType,
PlatformType, PlatformType,
WeixinServer, WeixinServer,
ErrorCodeType ErrorCodeType
} }
{ {
"name": "uni-open-bridge-common", "name": "uni-open-bridge-common",
"version": "1.0.0", "version": "1.0.0",
"description": "", "description": "",
"main": "index.js", "main": "index.js",
"scripts": { "scripts": {
"test": "echo \"Error: no test specified\" && exit 1" "test": "echo \"Error: no test specified\" && exit 1"
}, },
"keywords": [], "keywords": [],
"author": "", "author": "",
"license": "ISC", "license": "ISC",
"dependencies": { "dependencies": {
"uni-config-center": "file:../../../../../uni-config-center/uniCloud/cloudfunctions/common/uni-config-center" "uni-config-center": "file:..\/..\/..\/..\/..\/uni-config-center\/uniCloud\/cloudfunctions\/common\/uni-config-center"
} },
"origin-plugin-dev-name": "uni-open-bridge-common",
"origin-plugin-version": "1.2.1",
"plugin-dev-name": "uni-open-bridge-common",
"plugin-version": "1.2.1"
} }
\ No newline at end of file
'use strict'; 'use strict';
const { const {
Validator Validator
} = require('./validator.js') } = require('./validator.js')
const { const {
CacheKeyCascade CacheKeyCascade
} = require('./uni-cloud-cache.js') } = require('./uni-cloud-cache.js')
const { const {
BridgeError BridgeError
} = require('./bridge-error.js') } = require('./bridge-error.js')
class Storage { class Storage {
constructor(type, keys) { constructor(type, keys) {
this._type = type || null this._type = type || null
this._keys = keys || [] this._keys = keys || []
} }
async get(key, fallback) { async get(key, fallback) {
this.validateKey(key) this.validateKey(key)
const result = await this.create(key, fallback).get() const result = await this.create(key, fallback).get()
return result.value return result.value
} }
async set(key, value, expiresIn) { async set(key, value, expiresIn) {
this.validateKey(key) this.validateKey(key)
this.validateValue(value) this.validateValue(value)
const expires_in = this.getExpiresIn(expiresIn) const expires_in = this.getExpiresIn(expiresIn)
if (expires_in !== 0) { if (expires_in !== 0) {
await this.create(key).set(this.getValue(value), expires_in) await this.create(key).set(this.getValue(value), expires_in)
} }
} }
async remove(key) { async remove(key) {
this.validateKey(key) this.validateKey(key)
await this.create(key).remove() await this.create(key).remove()
} }
// virtual // virtual
async update(key) { async update(key) {
this.validateKey(key) this.validateKey(key)
} }
async ttl(key) { async ttl(key) {
this.validateKey(key) this.validateKey(key)
// 后续考虑支持 // 后续考虑支持
} }
async fallback(key) {} async fallback(key) {
return {
getKeyString(key) { value: null,
const keyArray = [Storage.Prefix] duration: -1
this._keys.forEach((name) => { }
keyArray.push(key[name]) }
})
keyArray.push(this._type) getKeyString(key) {
return keyArray.join(':') const keyArray = [Storage.Prefix]
} this._keys.forEach((name) => {
keyArray.push(key[name])
getValue(value) { })
return value keyArray.push(this._type)
} return keyArray.join(':')
}
getExpiresIn(value) {
if (value !== undefined) { getValue(value) {
return value return value
} }
return -1
} getExpiresIn(value) {
if (value !== undefined) {
validateKey(key) { return value
Validator.Key(this._keys, key) }
} return -1
}
validateValue(value) {
Validator.Value(value) validateKey(key) {
} Validator.Key(this._keys, key)
}
create(key, fallback) {
const keyString = this.getKeyString(key) validateValue(value) {
const options = { Validator.Value(value)
layers: [{ }
type: 'database',
key: keyString create(key, fallback) {
}, { const keyString = this.getKeyString(key)
type: 'redis', const options = {
key: keyString layers: [{
}] type: 'database',
} key: keyString
}, {
const _this = this type: 'redis',
return new CacheKeyCascade({ key: keyString
...options, }]
fallback: async function() { }
if (fallback) {
return fallback(key) const _this = this
} else if (_this.fallback) { return new CacheKeyCascade({
return _this.fallback(key) ...options,
} fallback: async function() {
} if (fallback) {
}) return fallback(key)
} } else if (_this.fallback) {
} return _this.fallback(key)
Storage.Prefix = "uni-id" }
}
module.exports = { })
Storage }
}
Storage.Prefix = "uni-id"
module.exports = {
Storage
}; };
const db = uniCloud.database() const db = uniCloud.database()
function getType(value) { function getType(value) {
return Object.prototype.toString.call(value).slice(8, -1).toLowerCase() return Object.prototype.toString.call(value).slice(8, -1).toLowerCase()
} }
const validator = { const validator = {
key: function(value) { key: function(value) {
const err = new Error('Invalid key') const err = new Error('Invalid key')
if (typeof value !== 'string') { if (typeof value !== 'string') {
throw err throw err
} }
const valueTrim = value.trim() const valueTrim = value.trim()
if (!valueTrim || valueTrim !== value) { if (!valueTrim || valueTrim !== value) {
throw err throw err
} }
}, },
value: function(value) { value: function(value) {
// 仅作简单校验 // 仅作简单校验
const type = getType(value) const type = getType(value)
const validValueType = ['null', 'number', 'string', 'array', 'object'] const validValueType = ['null', 'number', 'string', 'array', 'object']
if (validValueType.indexOf(type) === -1) { if (validValueType.indexOf(type) === -1) {
throw new Error('Invalid value type') throw new Error('Invalid value type')
} }
}, },
duration: function(value) { duration: function(value) {
const err = new Error('Invalid duration') const err = new Error('Invalid duration')
if (value === undefined) { if (value === undefined) {
return return
} }
if (typeof value !== 'number' || value === 0) { if (typeof value !== 'number' || value === 0) {
throw err throw err
} }
} }
} }
/** /**
* 入库时 expired 为过期时间对应的时间戳,永不过期用-1表示 * 入库时 expired 为过期时间对应的时间戳,永不过期用-1表示
* 返回结果时 与redis对齐,-1表示永不过期,-2表示已过期或不存在 * 返回结果时 与redis对齐,-1表示永不过期,-2表示已过期或不存在
*/ */
class DatabaseCache { class DatabaseCache {
constructor({ constructor({
collection = 'opendb-open-data' collection = 'opendb-open-data'
} = {}) { } = {}) {
this.type = 'db' this.type = 'db'
this.collection = db.collection(collection) this.collection = db.collection(collection)
} }
_serializeValue(value) { _serializeValue(value) {
return value === undefined ? null : JSON.stringify(value) return value === undefined ? null : JSON.stringify(value)
} }
_deserializeValue(value) { _deserializeValue(value) {
return value ? JSON.parse(value) : value return value ? JSON.parse(value) : value
} }
async set(key, value, duration) { async set(key, value, duration) {
validator.key(key) validator.key(key)
validator.value(value) validator.value(value)
validator.duration(duration) validator.duration(duration)
value = this._serializeValue(value) value = this._serializeValue(value)
await this.collection.doc(key).set({ await this.collection.doc(key).set({
value, value,
expired: duration && duration !== -1 ? Date.now() + (duration * 1000) : -1 expired: duration && duration !== -1 ? Date.now() + (duration * 1000) : -1
}) })
} }
async _getWithDuration(key) { async _getWithDuration(key) {
const getKeyRes = await this.collection.doc(key).get() const getKeyRes = await this.collection.doc(key).get()
const record = getKeyRes.data[0] const record = getKeyRes.data[0]
if (!record) { if (!record) {
return { return {
value: null, value: null,
duration: -2 duration: -2
} }
} }
const value = this._deserializeValue(record.value) const value = this._deserializeValue(record.value)
const expired = record.expired const expired = record.expired
if (expired === -1) { if (expired === -1) {
return { return {
value, value,
duration: -1 duration: -1
} }
} }
const duration = expired - Date.now() const duration = expired - Date.now()
if (duration <= 0) { if (duration <= 0) {
await this.remove(key) await this.remove(key)
return { return {
value: null, value: null,
duration: -2 duration: -2
} }
} }
return { return {
value, value,
duration: Math.floor(duration / 1000) duration: Math.floor(duration / 1000)
} }
} }
async get(key, { async get(key, {
withDuration = true withDuration = true
} = {}) { } = {}) {
const result = await this._getWithDuration(key) const result = await this._getWithDuration(key)
if (!withDuration) { if (!withDuration) {
delete result.duration delete result.duration
} }
return result return result
} }
async remove(key) { async remove(key) {
await this.collection.doc(key).remove() await this.collection.doc(key).remove()
} }
} }
class RedisCache { class RedisCache {
constructor() { constructor() {
this.type = 'redis' this.type = 'redis'
this.redis = uniCloud.redis() this.redis = uniCloud.redis()
} }
_serializeValue(value) { _serializeValue(value) {
return value === undefined ? null : JSON.stringify(value) return value === undefined ? null : JSON.stringify(value)
} }
_deserializeValue(value) { _deserializeValue(value) {
return value ? JSON.parse(value) : value return value ? JSON.parse(value) : value
} }
async set(key, value, duration) { async set(key, value, duration) {
validator.key(key) validator.key(key)
validator.value(value) validator.value(value)
validator.duration(duration) validator.duration(duration)
value = this._serializeValue(value) value = this._serializeValue(value)
if (!duration || duration === -1) { if (!duration || duration === -1) {
await this.redis.set(key, value) await this.redis.set(key, value)
} else { } else {
await this.redis.set(key, value, 'EX', duration) await this.redis.set(key, value, 'EX', duration)
} }
} }
async get(key, { async get(key, {
withDuration = false withDuration = false
} = {}) { } = {}) {
let value = await this.redis.get(key) let value = await this.redis.get(key)
value = this._deserializeValue(value) value = this._deserializeValue(value)
if (!withDuration) { if (!withDuration) {
return { return {
value value
} }
} }
const durationSecond = await this.redis.ttl(key) const durationSecond = await this.redis.ttl(key)
let duration let duration
switch (durationSecond) { switch (durationSecond) {
case -1: case -1:
duration = -1 duration = -1
break break
case -2: case -2:
duration = -2 duration = -2
break break
default: default:
duration = durationSecond duration = durationSecond
break break
} }
return { return {
value, value,
duration duration
} }
} }
async remove(key) { async remove(key) {
await this.redis.del(key) await this.redis.del(key)
} }
} }
class Cache { class Cache {
constructor({ constructor({
type, type,
collection collection
} = {}) { } = {}) {
if (type === 'database') { if (type === 'database') {
return new DatabaseCache({ return new DatabaseCache({
collection collection
}) })
} else if (type === 'redis') { } else if (type === 'redis') {
return new RedisCache() return new RedisCache()
} else { } else {
throw new Error('Invalid cache type') throw new Error('Invalid cache type')
} }
} }
} }
class CacheKey { class CacheKey {
constructor({ constructor({
type, type,
collection, collection,
cache, cache,
key, key,
fallback fallback
} = {}) { } = {}) {
this.cache = cache || new Cache({ this.cache = cache || new Cache({
type, type,
collection collection
}) })
this.key = key this.key = key
this.fallback = fallback this.fallback = fallback
} }
async set(value, duration) { async set(value, duration) {
await this.cache.set(this.key, value, duration) await this.cache.set(this.key, value, duration)
} }
async setWithSync(value, duration, syncMethod) { async setWithSync(value, duration, syncMethod) {
await Promise.all([ await Promise.all([
this.set(this.key, value, duration), this.set(this.key, value, duration),
syncMethod(value, duration) syncMethod(value, duration)
]) ])
} }
async get() { async get() {
let { let {
value, value,
duration duration
} = await this.cache.get(this.key) } = await this.cache.get(this.key)
if (value !== null && value !== undefined) { if (value !== null && value !== undefined) {
return { return {
value, value,
duration duration
} }
} }
if (!this.fallback) { if (!this.fallback) {
return { return {
value: null, value: null,
duration: -2 duration: -2
} }
} }
const fallbackResult = await this.fallback() const fallbackResult = await this.fallback()
value = fallbackResult.value value = fallbackResult.value
duration = fallbackResult.duration duration = fallbackResult.duration
if (value !== null && duration !== undefined) { if (value !== null && duration !== undefined) {
await this.cache.set(this.key, value, duration) await this.cache.set(this.key, value, duration)
} }
return { return {
value, value,
duration duration
} }
} }
async remove() { async remove() {
await this.cache.remove(this.key) await this.cache.remove(this.key)
} }
} }
class CacheKeyCascade { class CacheKeyCascade {
constructor({ constructor({
layers, // [{cache, type, collection, key}] 从低级到高级排序,[DbCacheKey, RedisCacheKey] layers, // [{cache, type, collection, key}] 从低级到高级排序,[DbCacheKey, RedisCacheKey]
fallback fallback
} = {}) { } = {}) {
this.layers = layers this.layers = layers
this.cacheLayers = [] this.cacheLayers = []
let lastCacheKey let lastCacheKey
for (let i = 0; i < layers.length; i++) { for (let i = 0; i < layers.length; i++) {
const { const {
type, type,
cache, cache,
collection, collection,
key key
} = layers[i] } = layers[i]
const lastCacheKeyTemp = lastCacheKey const lastCacheKeyTemp = lastCacheKey
try { try {
const currentCacheKey = new CacheKey({ const currentCacheKey = new CacheKey({
type, type,
collection, collection,
cache, cache,
key, key,
fallback: i === 0 ? fallback : function() { fallback: i === 0 ? fallback : function() {
return lastCacheKeyTemp.get() return lastCacheKeyTemp.get()
} }
}) })
this.cacheLayers.push(currentCacheKey) this.cacheLayers.push(currentCacheKey)
lastCacheKey = currentCacheKey lastCacheKey = currentCacheKey
} catch (e) {} } catch (e) {}
} }
this.highLevelCache = lastCacheKey this.highLevelCache = lastCacheKey
} }
async set(value, duration) { async set(value, duration) {
return Promise.all( return Promise.all(
this.cacheLayers.map(item => { this.cacheLayers.map(item => {
return item.set(value, duration) return item.set(value, duration)
}) })
) )
} }
async setWithSync(value, duration, syncMethod) { async setWithSync(value, duration, syncMethod) {
const setPromise = this.cacheLayers.map(item => { const setPromise = this.cacheLayers.map(item => {
return item.set(value, duration) return item.set(value, duration)
}) })
return Promise.all( return Promise.all(
[ [
...setPromise, ...setPromise,
syncMethod(value, duration) syncMethod(value, duration)
] ]
) )
} }
async get() { async get() {
return this.highLevelCache.get() return this.highLevelCache.get()
} }
async remove() { async remove() {
await Promise.all( await Promise.all(
this.cacheLayers.map(cacheKeyItem => { this.cacheLayers.map(cacheKeyItem => {
return cacheKeyItem.remove() return cacheKeyItem.remove()
}) })
) )
} }
} }
module.exports = { module.exports = {
Cache, Cache,
DatabaseCache, DatabaseCache,
RedisCache, RedisCache,
CacheKey, CacheKey,
CacheKeyCascade CacheKeyCascade
} }
const Validator = { const Validator = {
Key(keyArray, parameters) { Key(keyArray, parameters) {
for (let i = 0; i < keyArray.length; i++) { for (let i = 0; i < keyArray.length; i++) {
const keyName = keyArray[i] const keyName = keyArray[i]
if (typeof parameters[keyName] !== 'string') { if (typeof parameters[keyName] !== 'string') {
Validator.ThrowNewError(`Invalid ${keyName}`) Validator.ThrowNewError(`Invalid ${keyName}`)
} }
if (parameters[keyName].length < 1) { if (parameters[keyName].length < 1) {
Validator.ThrowNewError(`Invalid ${keyName}`) Validator.ThrowNewError(`Invalid ${keyName}`)
} }
} }
}, },
Value(value) { Value(value) {
if (value === undefined) { if (value === undefined) {
Validator.ThrowNewError('Invalid Value') Validator.ThrowNewError('Invalid Value')
} }
if (typeof value !== 'object') { if (typeof value !== 'object') {
Validator.ThrowNewError('Invalid Value Type') Validator.ThrowNewError('Invalid Value Type')
} }
}, },
ThrowNewError(message) { ThrowNewError(message) {
throw new Error(message) throw new Error(message)
} }
} }
module.exports = { module.exports = {
Validator Validator
} }
'use strict'; 'use strict';
const crypto = require('crypto') const crypto = require('crypto')
const { const {
HTTP_STATUS HTTP_STATUS
} = require('./consts.js') } = require('./consts.js')
const { const {
BridgeError BridgeError
} = require('./bridge-error.js') } = require('./bridge-error.js')
class WeixinServer { class WeixinServer {
constructor(options = {}) { constructor(options = {}) {
this._appid = options.appid this._appid = options.appid
this._secret = options.secret this._secret = options.secret
} }
getAccessToken() { getAccessToken() {
return uniCloud.httpclient.request(WeixinServer.AccessToken_Url, { return uniCloud.httpclient.request(WeixinServer.AccessToken_Url, {
dataType: 'json', dataType: 'json',
method: 'POST', method: 'POST',
contentType: 'json', contentType: 'json',
data: { data: {
appid: this._appid, appid: this._appid,
secret: this._secret, secret: this._secret,
grant_type: "client_credential" grant_type: "client_credential"
} }
}) })
} }
// 使用客户端获取的 code 从微信服务器换取 openid,code 仅可使用一次 // 使用客户端获取的 code 从微信服务器换取 openid,code 仅可使用一次
codeToSession(code) { codeToSession(code) {
return uniCloud.httpclient.request(WeixinServer.Code2Session_Url, { return uniCloud.httpclient.request(WeixinServer.Code2Session_Url, {
dataType: 'json', dataType: 'json',
data: { data: {
appid: this._appid, appid: this._appid,
secret: this._secret, secret: this._secret,
js_code: code, js_code: code,
grant_type: 'authorization_code' grant_type: 'authorization_code'
} }
}) })
} }
getUserEncryptKey({ getUserEncryptKey({
access_token, access_token,
openid, openid,
session_key session_key
}) { }) {
console.log(access_token, openid, session_key); console.log(access_token, openid, session_key);
const signature = crypto.createHmac('sha256', session_key).update('').digest('hex') const signature = crypto.createHmac('sha256', session_key).update('').digest('hex')
return uniCloud.httpclient.request(WeixinServer.User_Encrypt_Key_Url, { return uniCloud.httpclient.request(WeixinServer.User_Encrypt_Key_Url, {
dataType: 'json', dataType: 'json',
method: 'POST', method: 'POST',
dataAsQueryString: true, dataAsQueryString: true,
data: { data: {
access_token, access_token,
openid: openid, openid: openid,
signature: signature, signature: signature,
sig_method: 'hmac_sha256' sig_method: 'hmac_sha256'
} }
}) })
} }
getH5AccessToken() { getH5AccessToken() {
return uniCloud.httpclient.request(WeixinServer.AccessToken_H5_Url, { return uniCloud.httpclient.request(WeixinServer.AccessToken_H5_Url, {
dataType: 'json', dataType: 'json',
method: 'GET', method: 'GET',
data: { data: {
appid: this._appid, appid: this._appid,
secret: this._secret, secret: this._secret,
grant_type: "client_credential" grant_type: "client_credential"
} }
}) })
} }
getH5Ticket(access_token) { getH5Ticket(access_token) {
return uniCloud.httpclient.request(WeixinServer.Ticket_Url, { return uniCloud.httpclient.request(WeixinServer.Ticket_Url, {
dataType: 'json', dataType: 'json',
dataAsQueryString: true, dataAsQueryString: true,
method: 'POST', method: 'POST',
data: { data: {
access_token access_token
} }
}) })
} }
getH5AccessTokenForEip() { getH5AccessTokenForEip() {
return uniCloud.httpProxyForEip.postForm(WeixinServer.AccessToken_H5_Url, { return uniCloud.httpProxyForEip.postForm(WeixinServer.AccessToken_H5_Url, {
appid: this._appid, appid: this._appid,
secret: this._secret, secret: this._secret,
grant_type: "client_credential" grant_type: "client_credential"
}, { }, {
dataType: 'json' dataType: 'json'
}) })
} }
getH5TicketForEip(access_token) { getH5TicketForEip(access_token) {
return uniCloud.httpProxyForEip.postForm(WeixinServer.Ticket_Url, { return uniCloud.httpProxyForEip.postForm(WeixinServer.Ticket_Url, {
access_token access_token
}, { }, {
dataType: 'json', dataType: 'json',
dataAsQueryString: true dataAsQueryString: true
}) })
} }
} }
WeixinServer.AccessToken_Url = 'https://api.weixin.qq.com/cgi-bin/stable_token' WeixinServer.AccessToken_Url = 'https://api.weixin.qq.com/cgi-bin/stable_token'
WeixinServer.Code2Session_Url = 'https://api.weixin.qq.com/sns/jscode2session' WeixinServer.Code2Session_Url = 'https://api.weixin.qq.com/sns/jscode2session'
WeixinServer.User_Encrypt_Key_Url = 'https://api.weixin.qq.com/wxa/business/getuserencryptkey' WeixinServer.User_Encrypt_Key_Url = 'https://api.weixin.qq.com/wxa/business/getuserencryptkey'
WeixinServer.AccessToken_H5_Url = 'https://api.weixin.qq.com/cgi-bin/token' WeixinServer.AccessToken_H5_Url = 'https://api.weixin.qq.com/cgi-bin/token'
WeixinServer.Ticket_Url = 'https://api.weixin.qq.com/cgi-bin/ticket/getticket?type=jsapi' WeixinServer.Ticket_Url = 'https://api.weixin.qq.com/cgi-bin/ticket/getticket?type=jsapi'
WeixinServer.GetMPAccessToken = function(options) { WeixinServer.GetMPAccessToken = function(options) {
return new WeixinServer(options).getAccessToken() return new WeixinServer(options).getAccessToken()
} }
WeixinServer.GetCodeToSession = function(options) { WeixinServer.GetCodeToSession = function(options) {
return new WeixinServer(options).codeToSession(options.code) return new WeixinServer(options).codeToSession(options.code)
} }
WeixinServer.GetUserEncryptKey = function(options) { WeixinServer.GetUserEncryptKey = function(options) {
return new WeixinServer(options).getUserEncryptKey(options) return new WeixinServer(options).getUserEncryptKey(options)
} }
WeixinServer.GetH5AccessToken = function(options) { WeixinServer.GetH5AccessToken = function(options) {
return new WeixinServer(options).getH5AccessToken() return new WeixinServer(options).getH5AccessToken()
} }
WeixinServer.GetH5Ticket = function(options) { WeixinServer.GetH5Ticket = function(options) {
return new WeixinServer(options).getH5Ticket(options.access_token) return new WeixinServer(options).getH5Ticket(options.access_token)
} }
//////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////
function isAliyun() { function isAliyun() {
return (uniCloud.getCloudInfos()[0].provider === 'aliyun') return (uniCloud.getCloudInfos()[0].provider === 'aliyun')
} }
WeixinServer.GetResponseData = function(response) { WeixinServer.GetResponseData = function(response) {
console.log("WeixinServer::response", response) console.log("WeixinServer::response", response)
if (!(response.status === HTTP_STATUS.SUCCESS || response.statusCodeValue === HTTP_STATUS.SUCCESS)) { if (!(response.status === HTTP_STATUS.SUCCESS || response.statusCodeValue === HTTP_STATUS.SUCCESS)) {
throw new BridgeError(response.status || response.statusCodeValue, response.status || response.statusCodeValue) throw new BridgeError(response.status || response.statusCodeValue, response.status || response.statusCodeValue)
} }
const responseData = response.data || response.body const responseData = response.data || response.body
if (responseData.errcode !== undefined && responseData.errcode !== 0) { if (responseData.errcode !== undefined && responseData.errcode !== 0) {
throw new BridgeError(responseData.errcode, responseData.errmsg) throw new BridgeError(responseData.errcode, responseData.errmsg)
} }
return responseData return responseData
} }
WeixinServer.GetMPAccessTokenData = async function(options) { WeixinServer.GetMPAccessTokenData = async function(options) {
const response = await new WeixinServer(options).getAccessToken() const response = await new WeixinServer(options).getAccessToken()
return WeixinServer.GetResponseData(response) return WeixinServer.GetResponseData(response)
} }
WeixinServer.GetCodeToSessionData = async function(options) { WeixinServer.GetCodeToSessionData = async function(options) {
const response = await new WeixinServer(options).codeToSession(options.code) const response = await new WeixinServer(options).codeToSession(options.code)
return WeixinServer.GetResponseData(response) return WeixinServer.GetResponseData(response)
} }
WeixinServer.GetUserEncryptKeyData = async function(options) { WeixinServer.GetUserEncryptKeyData = async function(options) {
const response = await new WeixinServer(options).getUserEncryptKey(options) const response = await new WeixinServer(options).getUserEncryptKey(options)
return WeixinServer.GetResponseData(response) return WeixinServer.GetResponseData(response)
} }
WeixinServer.GetH5AccessTokenData = async function(options) { WeixinServer.GetH5AccessTokenData = async function(options) {
const ws = new WeixinServer(options) const ws = new WeixinServer(options)
let response let response
if (isAliyun()) { if (isAliyun()) {
response = await ws.getH5AccessTokenForEip() response = await ws.getH5AccessTokenForEip()
if (typeof response === 'string') { if (typeof response === 'string') {
response = JSON.parse(response) response = JSON.parse(response)
} }
} else { } else {
response = await ws.getH5AccessToken() response = await ws.getH5AccessToken()
} }
return WeixinServer.GetResponseData(response) return WeixinServer.GetResponseData(response)
} }
WeixinServer.GetH5TicketData = async function(options) { WeixinServer.GetH5TicketData = async function(options) {
const ws = new WeixinServer(options) const ws = new WeixinServer(options)
let response let response
if (isAliyun()) { if (isAliyun()) {
response = await ws.getH5TicketForEip(options.access_token) response = await ws.getH5TicketForEip(options.access_token)
if (typeof response === 'string') { if (typeof response === 'string') {
response = JSON.parse(response) response = JSON.parse(response)
} }
} else { } else {
response = await ws.getH5Ticket(options.access_token) response = await ws.getH5Ticket(options.access_token)
} }
return WeixinServer.GetResponseData(response) return WeixinServer.GetResponseData(response)
} }
module.exports = { module.exports = {
WeixinServer WeixinServer
} }
// 文档教程: https://uniapp.dcloud.net.cn/uniCloud/schema // 文档教程: https://uniapp.dcloud.net.cn/uniCloud/schema
{ {
"bsonType": "object", "bsonType": "object",
"required": ["_id", "value"], "required": ["_id", "value"],
"properties": { "properties": {
"_id": { "_id": {
"bsonType": "string", "bsonType": "string",
"description": "key,格式:uni-id:[provider]:[appid]:[openid]:[access-token|user-access-token|session-key|encrypt-key-version|ticket]" "description": "key,格式:uni-id:[provider]:[appid]:[openid]:[access-token|user-access-token|session-key|encrypt-key-version|ticket]"
}, },
"value": { "value": {
"bsonType": "object", "bsonType": "object",
"description": "字段_id对应的值" "description": "字段_id对应的值"
}, },
"expired": { "expired": {
"bsonType": "date", "bsonType": "date",
"description": "过期时间" "description": "过期时间"
} }
} }
} }
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册