В последнее время, поскольку бизнес компании работал над проектом апплета WeChat, я воспользовался этой возможностью, чтобы подвести итоги и записать некоторые из ям, на которые я недавно наступил.
Связано со входом в апплет WeChat
- Внешний интерфейс вызывает wx.login() для получения временных учетных данных для входа.code
- Отправьте код на сервер через wx.request() (требуется, чтобы бэкенд создал интерфейс для получения кода)
- Серверная часть выполняет проверку учетных данных для входа, а входные параметры (appid, secret, js_code, grant_type)
Объяснение общих терминов:
уникальный идентификатор апплета appid секретное приложение секрет апплета js_code Код, полученный при входе в систему Заполните grant_type как авторизация_код
- Если учетные данные для входа проверены, openid и session_key будут обменены с сервера WeChat.
уникальный идентификатор пользователя openid session_key сеансовый ключ
openid — это уникальный идентификатор пользователя, но его не рекомендуется использовать непосредственно в качестве идентификатора внутреннего сервера. session_key — это пароль для шифрования и подписи пользовательских данных. Session_key требуется для проверки файлов и получения информации о пользователе.
Как правило, из соображений безопасности ни один из этих двух данных не будет отправлен клиенту.
- После того, как серверная часть обрабатывает session_key, она возвращает обработанную строку во внешний интерфейс в качестве идентификатора входа пользователя, обычно в виде токена. (Пользовательский статус входа связан с openid session_key)
- Внешний интерфейс получает токен, сохраняет его в localStorage и берет с собой каждый раз, когда запрашивает данные с сервера в качестве учетных данных сервера для идентификации пользователя.
- Когда следующий пользователь входит в апплет, сначала вызовите wx.checkSession(), чтобы проверить статус входа в систему, и, если это не удастся, повторно инициируйте процесс входа.
//app.js
const NOLOGINCODE = 1000003 //未登录
const SUCCESS = 1000001 //成功
App({
onLaunch: function() {
var loginFlag = wx.getStorageSync('sessionId')
var that = this
if (loginFlag) {
// 检查 session_key 是否过期
wx.checkSession({
// session_key 有效(未过期)
success: function() {
var userInfo = wx.getStorageSync('wxUserInfo')
if (userInfo) {
that.globalData.hasUserInfo = true
}
},
// session_key 过期
fail: function() {
// session_key过期,重新登录
that.doLogin()
}
})
} else {
// 无skey,作为首次登录
this.doLogin()
}
},
doLogin() {
this.log().then(res => {
this.$post('/auth', { code: res.code }, false).then(data => {
wx.setStorageSync('sessionId', data.sessionId)
})
})
},
/**
*微信登录 获取code值,并将code传递给服务器
* @returns
*/
log() {
return new Promise(resolve => {
wx.login({
success(res) {
if (res.errMsg === 'login:ok') {
resolve(res)
} else {
wx.showToast({
title: '微信登录失败',
icon: 'none',
duration: 1200
})
}
},
fail() {
wx.showToast({
title: '微信登录接口调用失败',
icon: 'none',
duration: 1200
})
}
})
})
},
globalData: {
baseurl: 'https://www.fake.shop'
}
})
инкапсуляция сетевых запросов
API сетевого запроса в апплете WeChat — wx.request(), но этот запрос в виде асинхронного обратного вызова, при каждой отправке запроса должна быть написана длинная строка, и если это вложенный запрос , вы обнаружите, что код написан довольно раздутым, поэтому создание Promisefy практически необходимо. код показывает, как показано ниже:
$get(url, data = {}, needToken = true) {
let SUCCESS = 200
var that = this
needToken ? (data.token = wx.getStorageSync('ToKen')) : ''
return new Promise((resolve, reject) => {
wx.request({
url: that.globalData.baseurl + url,
method: "GET",
header: {
'content-type': 'application/json'
},
data: data,
success(e) {
if (e.data.code == SUCCESS) {
resolve(e.data)
return
}
},
fail(e) {
wx.showModal({
title: '提示',
content: '请求失败',
showCancel: false
})
reject(e)
}
})
})
},
$post(url, data = {}, needToken = true) {
let that = this
let SUCCESS = 200
let TimeOut = 1000
var that = this
needToken ? (data.token = wx.getStorageSync('ToKen')) : ''
return new Promise((resolve, reject) => {
wx.request({
url: that.globalData.baseurl + url,
method: "POST",
//此处可以根据接口文档设置header头
// header: {
// 'content-type': 'application/x-www-form-urlencoded'
// },
data: data,
success(e) {
if (e.statusCode == SUCCESS) {
if (e.data.code == SUCCESS) {
resolve(e.data)
}
else {
reject(e)
wx.showModal({
title: '提示',
content: e.data.msg,
showCancel: false,
success: function (res) {
if (res.confirm) {
if (e.data.code == TimeOut) { //根据实际业务返回的code码判断是否过期
// 登录过期
that.doLogin();
}
}
}
})
}
} else {
wx.showModal({
title: '提示',
content: e.data.error,
showCancel: false
})
reject(e)
}
},
fail(e) {
console.log(e)
wx.showModal({
title: '提示',
content: '请求失败',
showCancel: false
})
reject(e)
},
complete(e) {
}
})
})
},
Оплата официальной учетной записи WeChat (браузер WeChat)
Хоть я и пишу гайд по ступлению на яму маленькой программы, сходство между оплатой на странице Н5 в WeChat и оплатой в маленькой программе все же есть, так что запишем, кстати.
Сценарии применения
- Уже существует веб-сайт торгового центра H5.Когда пользователи открывают веб-страницу в WeChat через сообщение или сканируют QR-код, они могут вызвать оплату WeChat, чтобы завершить процесс размещения заказа и покупки.
Подготовить
UnionID: чтобы идентифицировать пользователей, каждый пользователь будет генерировать безопасный OpenID для каждой официальной учетной записи.Если вам нужно разделить пользователей между несколькими официальными учетными записями и мобильными приложениями, вам нужно перейти на открытую платформу WeChat, чтобы связать эти официальные учетные записи и приложения. , Назначенный учетной записи открытой платформы, после привязки, хотя у пользователя есть несколько разных OpenID для нескольких официальных учетных записей и приложений, у него есть только один UnionID для всех этих официальных учетных записей и приложений под одной и той же учетной записью открытой платформы. Авторизация веб-страницы: в некоторых сложных бизнес-сценариях услуги должны предоставляться в виде веб-страниц, и openid пользователя может быть получен через авторизацию веб-страницы (Примечание: согласие пользователя не требуется для получения OpenID пользователя, и согласие пользователя требуется для получения основной информации о пользователе) WeChat JS-SDK: это набор инструментов для разработчиков, позволяющий использовать встроенные функции WeChat на веб-страницах с помощью кода JavaScript. Разработчики могут использовать его для записи и воспроизведения голоса WeChat на веб-страницах, мониторинга совместного использования WeChat, загрузки локальных изображений на мобильные телефоны, фотографирования. , и многие другие возможности.
Диаграмма последовательности бизнес-процессов
Основной процесс
- Есть два основных типа jssdk, представленных на веб-страницах.
- Вставьте следующие файлы JS на страницу, которая должна вызывать интерфейс JS:Горячая вода Думаю QQ.com/open/is/price… Шаги использования JSSDK
- Импорт модуля: Непосредственно импортировать пакеты npmweixin-js-sdk, который можно установить напрямую через npm, а затем ссылаться непосредственно в необходимых файлах.
- Авторизация веб-страницы
- Насколько я понимаю, авторизация веб-страницы в основном предназначена для того, чтобы сторонние веб-страницы, открытые в браузере WeChat, могли выполнять операции, связанные с общедоступной учетной записью WeChat и WeChat пользователя, и, наконец, получать общедоступную учетную запись пользователя под общедоступной учетной записью.openid.
- Приложение веб-сайта WeChat login — это авторизованная система авторизации WeChat OAuth2.0, основанная на стандарте протокола OAuth2.0. Получение openid разделено на два шага
- Внешний интерфейс получает код через URL-адрес перехода, а затем отправляет код на серверную часть.
- Затем серверная часть получает openid на основе кода.
получить код
- Прежде чем официальная учетная запись WeChat запросит авторизацию веб-страницы пользователя, разработчику необходимо перейти к параметру конфигурации «Разработка — Разрешение интерфейса — Веб-служба — Веб-учетная запись — Веб-авторизация для получения основной информации о пользователе» на официальном веб-сайте официальной платформы. и измените доменное имя обратного вызова авторизации. В этом примере имя домена обратного вызоваwww.foo.com
- Пример бизнес-процесса: Адрес платежной страницы: payUrl => "www.foo.com/pay1. Когда вы хотите перейти на страницу оплаты, если онаБраузер WeChatПерейти непосредственно к href (существует множество способов перенаправления или location.href) на "open.WeChat.QQ.com/connect/OA U…"+ appid +"&redirect_uri="+ URLEncoder.encode(payUrl) +"&response_type=code&scope=snsapi_base&state=123#wechat_redirect" 2. Система автоматически перейдет к payUrl и вернет код параметра, такой как => "Woohoo.ah ah.com/ Боюсь, что есть?code=ah ah...3. Затем прочитать код и отправить бэкенд, чтобы все было в порядке, это должны знать все.
Примечание:
URLEncoder.encode(payUrl) очень нужен Параметр состояния: используется для поддержания состояния запроса и обратного вызова, а также для передачи его третьей стороне в том виде, в каком оно есть после авторизации запроса. Этот параметр можно использовать для предотвращения csrf-атак (атаки с подделкой межсайтовых запросов). Рекомендуется, чтобы этот параметр привносили третьи лица. Для проверки можно установить простое случайное число плюс сессию. Причина, по которой бэкэнд получает openid: Поскольку я являюсь фронтендом, я не хочу этого делать (шучу 😜), на самом деле это может быть в основном потому, что эта часть логики чувствительнаоткрытый ключи т. д., а также во избежание междоменных проблем с внешним интерфейсом. Код является ограничением по времени: код используется в качестве билета в обмен на access_token, и код при авторизации каждого пользователя будет разным.Код можно использовать только один раз, и срок его действия автоматически истечет, если он не используется в течение 5 минут.Таким образом, каждый раз, когда вы совершаете платеж, вам нужно выполнять описанную выше логику.
Оплата перевода H5 в WeChat
- Openid и номер заказа продавца должны быть отправлены на серверную часть, и серверная часть вызывает API для генерации конфигурации, необходимой интерфейсу для вызова платежного jsapi (в основном это логика серверной части) Без лишних слов, код выглядит следующим образом:
//this.wechaConfig 里面保存的是后端调用预支付api 以后传递给前端用来调用getBrandWCPayRequest 的配置项。
let config = {
appId: this.wechaConfig.appId + '', // 公众号名称,由商户传入
timeStamp: this.wechaConfig.timeStamp + '', // 时间戳,自 1970 年以来的秒数
nonceStr: this.wechaConfig.nonceStr + '', // 随机串
package: this.wechaConfig.package + '', // 统一下单接口返回的 prepay_id 参数值,提交格式如:prepay_id=***
signType: this.wechaConfig.signType + '', // 微信签名方式:
paySign: this.wechaConfig.paySign + '', // 微信签名
}
// config = JSON.parse(JSON.stringify(config))
WeixinJSBridge.invoke(
'getBrandWCPayRequest',
config,
function(res) {
if (res.err_msg == 'get_brand_wcpay_request:ok') {
// 使用以上方式判断前端返回, 微信团队郑重提示:res.err_msg 将在用户支付成功后返回 ok,但并不保证它绝对可靠。
this.$router.push({
name: 'payResult',
query: {
status: true,
id: this.addOrder.orderId,
},
})
} else {
this.$router.push({
name: 'payResult',
query: {
status: false,
},
})
}
}.bind(this)
)
Уведомление:
- Если вы используете wx.choosewxpay(), то в поле конфигурации указывается TimeStamp вместо TimeStamp
- Причина, по которой каждая переменная в переменной конфигурации добавляется с помощью «», например: this.wechaconfig.Appid + '', поскольку до того, как она была добавлена, платеж WeChat можно нормально вызывать на Android, но при тестировании на iOS это будет Сообщите о отсутствии jsapi appid или отсутствия jsapackage (что, черт возьми, в моем сердце в то время (((m -__-) m я явно передал его), поэтому плюс много информации, искал, сказала, что это был json Задача формата, я думаю, это может быть, потому что это очень странно, причина (рассужденный и чистый большой парень прокомментировал область комментариев), значение APPID не анализируется как тип строки, поэтому я добавил это, чтобы это было справиться с этим.
Один из наиболее полезных найденных заключается в том, что проблема заключается в том, что при оплате параметры JSON должны быть полностью строковыми. Например, моя ошибка в том, что в параметре {"timeStamp":12312312} значение timestamp целое число. Хотя на Android это можно оплатить, на IOS нельзя. Это должно быть строго по документ.Ключи и значения - все символы.строка! Так что {"timeStamp":"12312312"} > правильно!портал
- Если вы выполняете локальную отладку, обратите внимание, что интерфейс WeChat по умолчанию использует порт 80.
Первоначальной целью написания этой статьи было записать ямы, на которые я наступал, чтобы мои друзья не наступали на ямы повторно. Похоже, что контента все еще относительно мало, и он будет обновляться в будущем. . .