提交 4cbe46d6 编写于 作者: 雪洛's avatar 雪洛

feat: secureNetworkHandshakeByWeixin

上级 af79f313
......@@ -6,6 +6,8 @@ const verifyCollectionName = 'opendb-verify-codes'
const verifyCollection = db.collection(verifyCollectionName)
const deviceCollectionName = 'uni-id-device'
const deviceCollection = db.collection(deviceCollectionName)
const openDataCollectionName = 'opendb-open-data'
const openDataCollection = db.collection(openDataCollectionName)
const USER_IDENTIFIER = {
username: 'username',
......@@ -78,6 +80,7 @@ module.exports = {
userCollection,
verifyCollection,
deviceCollection,
openDataCollection,
USER_IDENTIFIER,
USER_STATUS,
CAPTCHA_SCENE,
......
......@@ -63,7 +63,8 @@ const {
} = require('./module/verify/index')
const {
refreshToken,
setPushCid
setPushCid,
secureNetworkHandshakeByWeixin
} = require('./module/utils/index')
const {
getInvitedUser,
......@@ -576,5 +577,9 @@ module.exports = {
* @tutorial https://uniapp.dcloud.net.cn/uniCloud/uni-id-pages.html#unbind-apple
* @returns
*/
unbindApple
unbindApple,
/**
* 安全网络握手,目前仅处理微信小程序安全网络握手
*/
secureNetworkHandshakeByWeixin
}
let redisEnable = null
function getRedisEnable() {
// 未用到的时候不调用redis接口,节省一些连接数
if (redisEnable !== null) {
return redisEnable
}
try {
uniCloud.redis()
redisEnable = true
} catch (error) {
redisEnable = false
}
return redisEnable
}
module.exports = {
getRedisEnable
}
\ No newline at end of file
......@@ -5,8 +5,14 @@ const {
const {
ERROR
} = require('../../common/error')
const {
getRedisEnable
} = require('./utils')
const {
openDataCollection
} = require('../../common/constants')
function decryptWeixinData ({
function decryptWeixinData({
encryptedData,
sessionKey,
iv
......@@ -31,7 +37,7 @@ function decryptWeixinData ({
return decoded
}
function getWeixinPlatform () {
function getWeixinPlatform() {
const platform = this.clientPlatform
const userAgent = this.getClientInfo().userAgent
switch (platform) {
......@@ -48,7 +54,7 @@ function getWeixinPlatform () {
}
}
async function saveWeixinUserKey ({
async function saveWeixinUserKey({
openid,
sessionKey, // 微信小程序用户sessionKey
accessToken, // App端微信用户accessToken
......@@ -85,7 +91,36 @@ async function saveWeixinUserKey ({
}
}
function generateWeixinCache ({
async function saveSecureNetworkCache({
code,
openid,
unionid,
sessionKey
}) {
const {
appId
} = this.getClientInfo()
const key = `uni-id:${appId}:weixin-mp:code:${code}:secure-network-cache`
const value = JSON.stringify({
openid,
unionid,
session_key: sessionKey
})
// 此处存储的是code的缓存,有效期两天即可
const expiredSeconds = 2 * 24 * 60 * 60
await openDataCollection.doc(key).set({
value,
expired: Date.now() + expiredSeconds * 1000
})
const isRedisEnable = getRedisEnable()
if (isRedisEnable) {
const redis = uniCloud.redis()
await redis.set(key, value, 'EX', expiredSeconds)
}
}
function generateWeixinCache({
sessionKey, // 微信小程序用户sessionKey
accessToken, // App端微信用户accessToken
refreshToken, // App端微信用户refreshToken
......@@ -118,7 +153,7 @@ function generateWeixinCache ({
}
}
function getWeixinOpenid ({
function getWeixinOpenid({
userRecord
} = {}) {
const weixinPlatform = getWeixinPlatform.call(this)
......@@ -130,7 +165,7 @@ function getWeixinOpenid ({
return wxOpenidObj[`${weixinPlatform}_${appId}`] || wxOpenidObj[weixinPlatform]
}
async function getWeixinCacheFallback ({
async function getWeixinCacheFallback({
userRecord,
key
} = {}) {
......@@ -143,7 +178,7 @@ async function getWeixinCacheFallback ({
return weixinCache && weixinCache[key]
}
async function getWeixinCache ({
async function getWeixinCache({
uid,
userRecord,
key
......@@ -177,7 +212,7 @@ async function getWeixinCache ({
})
}
async function getWeixinAccessToken () {
async function getWeixinAccessToken() {
const weixinPlatform = getWeixinPlatform.call(this)
const appId = this.getClientInfo().appId
......@@ -194,5 +229,6 @@ module.exports = {
generateWeixinCache,
getWeixinCache,
saveWeixinUserKey,
getWeixinAccessToken
getWeixinAccessToken,
saveSecureNetworkCache
}
......@@ -2,10 +2,7 @@ const {
initWeixin
} = require('../../lib/third-party/index')
const {
getWeixinPlatform,
getWeixinAccessToken,
generateWeixinCache,
saveWeixinUserKey
getWeixinAccessToken
} = require('../../lib/utils/weixin')
const {
ERROR
......
......@@ -11,7 +11,8 @@ const {
const {
generateWeixinCache,
getWeixinPlatform,
saveWeixinUserKey
saveWeixinUserKey,
saveSecureNetworkCache
} = require('../../lib/utils/weixin')
const {
LOG_TYPE
......@@ -37,7 +38,9 @@ module.exports = async function (params = {}) {
this.middleware.validate(params, schema)
const {
code,
inviteCode
inviteCode,
// 内部参数,暂不暴露
secureNetworkCache = false
} = params
const {
appId
......@@ -81,6 +84,18 @@ module.exports = async function (params = {}) {
expired: accessTokenExpired // App端微信用户accessToken过期时间
} = getWeixinAccountResult
if (secureNetworkCache) {
if (weixinPlatform !== 'mp') {
throw new Error('Unsupported weixin platform, expect mp-weixin')
}
await saveSecureNetworkCache({
code,
openid,
unionid,
sessionKey
})
}
const {
type,
user
......
module.exports = {
refreshToken: require('./refresh-token'),
setPushCid: require('./set-push-cid')
setPushCid: require('./set-push-cid'),
secureNetworkHandshakeByWeixin: require('./secure-network-handshake-by-weixin')
}
const {
ERROR
} = require('../../common/error')
const {
initWeixin
} = require('../../lib/third-party/index')
const {
saveWeixinUserKey,
saveSecureNetworkCache
} = require('../../lib/utils/weixin')
const loginByWeixin = require('../login/login-by-weixin')
/**
* 微信安全网络握手
* @tutorial https://uniapp.dcloud.net.cn/uniCloud/uni-id-pages.html#set-push-cid
* @param {object} params
* @param {string} params.code 微信登录返回的code
* @param {boolean} params.callLoginByWeixin 是否同时调用一次微信登录
* @returns
*/
module.exports = async function (params = {}) {
const schema = {
code: 'string',
callLoginByWeixin: {
type: 'boolean',
required: false
}
}
this.middleware.validate(params, schema)
let platform = this.clientPlatform
if (platform !== 'mp-weixin') {
throw new Error(`[secureNetworkHandshake] platform ${platform} is not supported`)
}
const {
code,
callLoginByWeixin = false
} = params
if (callLoginByWeixin) {
return loginByWeixin.call(this, {
code,
secureNetworkCache: true
})
}
const weixinApi = initWeixin.call(this)
let getWeixinAccountResult
try {
getWeixinAccountResult = await weixinApi.code2Session(code)
} catch (error) {
console.error(error)
throw {
errCode: ERROR.GET_THIRD_PARTY_ACCOUNT_FAILED
}
}
const {
openid,
unionid,
sessionKey // 微信小程序用户sessionKey
} = getWeixinAccountResult
await saveSecureNetworkCache.call(this, {
code,
openid,
unionid,
sessionKey
})
await saveWeixinUserKey.call(this, {
openid,
sessionKey
})
return {
errCode: 0
}
}
......@@ -14,6 +14,10 @@
"uni-open-bridge-common": "file:../../../../uni-open-bridge-common/uniCloud/cloudfunctions/common/uni-open-bridge-common"
},
"extensions": {
"uni-cloud-sms": {}
"uni-cloud-sms": {},
"uni-cloud-redis": {}
},
"cloudfunction-config": {
"keepRunningAfterReturn": false
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册