123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186 |
- const crypto = require('crypto')
- const {
- userCollection
- } = require('../../common/constants')
- const {
- ERROR
- } = require('../../common/error')
- function decryptWeixinData ({
- encryptedData,
- sessionKey,
- iv
- } = {}) {
- const oauthConfig = this.configUtils.getOauthConfig({
- provider: 'weixin'
- })
- const decipher = crypto.createDecipheriv(
- 'aes-128-cbc',
- Buffer.from(sessionKey, 'base64'),
- Buffer.from(iv, 'base64')
- )
- // 设置自动 padding 为 true,删除填充补位
- decipher.setAutoPadding(true)
- let decoded
- decoded = decipher.update(encryptedData, 'base64', 'utf8')
- decoded += decipher.final('utf8')
- decoded = JSON.parse(decoded)
- if (decoded.watermark.appid !== oauthConfig.appid) {
- throw new Error('Invalid wechat appid in decode content')
- }
- return decoded
- }
- function getWeixinPlatform () {
- const platform = this.clientPlatform
- const userAgent = this.getClientInfo().userAgent
- switch (platform) {
- case 'app':
- case 'app-plus':
- return 'app'
- case 'mp-weixin':
- return 'mp'
- case 'h5':
- case 'web':
- return userAgent.indexOf('MicroMessenger') > -1 ? 'h5' : 'web'
- default:
- throw new Error('Unsupported weixin platform')
- }
- }
- async function saveWeixinUserKey ({
- openid,
- sessionKey, // 微信小程序用户sessionKey
- accessToken, // App端微信用户accessToken
- refreshToken, // App端微信用户refreshToken
- accessTokenExpired // App端微信用户accessToken过期时间
- } = {}) {
- // 微信公众平台、开放平台refreshToken有效期均为30天(微信没有在网络请求里面返回30天这个值,务必注意未来可能出现调整,需及时更新此处逻辑)。
- // 此前QQ开放平台有调整过accessToken的过期时间:[access_token有效期由90天缩短至30天](https://wiki.connect.qq.com/%E3%80%90qq%E4%BA%92%E8%81%94%E3%80%91access_token%E6%9C%89%E6%95%88%E6%9C%9F%E8%B0%83%E6%95%B4)
- const appId = this.getClientInfo().appId
- const weixinPlatform = getWeixinPlatform.call(this)
- const keyObj = {
- dcloudAppid: appId,
- openid,
- platform: 'weixin-' + weixinPlatform
- }
- switch (weixinPlatform) {
- case 'mp':
- await this.uniOpenBridge.setSessionKey(keyObj, {
- session_key: sessionKey
- }, 30 * 24 * 60 * 60)
- break
- case 'app':
- case 'h5':
- case 'web':
- await this.uniOpenBridge.setUserAccessToken(keyObj, {
- access_token: accessToken,
- refresh_token: refreshToken,
- access_token_expired: accessTokenExpired
- }, 30 * 24 * 60 * 60)
- break
- default:
- break
- }
- }
- function generateWeixinCache ({
- sessionKey, // 微信小程序用户sessionKey
- accessToken, // App端微信用户accessToken
- refreshToken, // App端微信用户refreshToken
- accessTokenExpired // App端微信用户accessToken过期时间
- } = {}) {
- const platform = getWeixinPlatform.call(this)
- let cache
- switch (platform) {
- case 'app':
- case 'h5':
- case 'web':
- cache = {
- access_token: accessToken,
- refresh_token: refreshToken,
- access_token_expired: accessTokenExpired
- }
- break
- case 'mp':
- cache = {
- session_key: sessionKey
- }
- break
- default:
- throw new Error('Unsupported weixin platform')
- }
- return {
- third_party: {
- [`${platform}_weixin`]: cache
- }
- }
- }
- function getWeixinOpenid ({
- userRecord
- } = {}) {
- const weixinPlatform = getWeixinPlatform.call(this)
- const appId = this.getClientInfo().appId
- const wxOpenidObj = userRecord.wx_openid
- if (!wxOpenidObj) {
- return
- }
- return wxOpenidObj[`${weixinPlatform}_${appId}`] || wxOpenidObj[weixinPlatform]
- }
- async function getWeixinCacheFallback ({
- userRecord,
- key
- } = {}) {
- const platform = getWeixinPlatform.call(this)
- const thirdParty = userRecord && userRecord.third_party
- if (!thirdParty) {
- return
- }
- const weixinCache = thirdParty[`${platform}_weixin`]
- return weixinCache && weixinCache[key]
- }
- async function getWeixinCache ({
- uid,
- userRecord,
- key
- } = {}) {
- const weixinPlatform = getWeixinPlatform.call(this)
- const appId = this.getClientInfo().appId
- if (!userRecord) {
- const getUserRes = await userCollection.doc(uid).get()
- userRecord = getUserRes.data[0]
- }
- if (!userRecord) {
- throw {
- errCode: ERROR.ACCOUNT_NOT_EXISTS
- }
- }
- const openid = getWeixinOpenid.call(this, {
- userRecord
- })
- const getCacheMethod = weixinPlatform === 'mp' ? 'getSessionKey' : 'getUserAccessToken'
- const userKey = await this.uniOpenBridge[getCacheMethod]({
- dcloudAppid: appId,
- platform: 'weixin-' + weixinPlatform,
- openid
- })
- if (userKey) {
- return userKey[key]
- }
- return getWeixinCacheFallback({
- userRecord,
- key
- })
- }
- module.exports = {
- decryptWeixinData,
- getWeixinPlatform,
- generateWeixinCache,
- getWeixinCache,
- saveWeixinUserKey
- }
|