English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

Пять первых ловушек при разработке微信-аккаунта php (часть 1)

Прямо к делу:

Документация по разработке微信 общественных аккаунтов, официальная версия (https://mp.weixin.qq.com/wiki), поверьте мне, я уже не могу терпеть того, кто написал этот документ, я真心想砸键盘,但当我动手的时候才发现,原来键盘 я сам купил.... Прикольно. 

Не будем тратить время на пустые разговоры, давайте сразу перейдем к тому, как部署ить и как разработать. 

Сначала у вас должен быть аккаунт общественной платформы, хорошо, начнем считать кувшины. 

Первый кувшин,Не думайте, что если это не корпоративный аккаунт, вы не можете разрабатывать, вы можете подать заявку на тестовый аккаунт, это больше, чем интерфейсы подписки.

 

Войдите в backstage управления, нажмите на разработчикские инструменты, вы можете увидеть тестовый аккаунт общественной платформы, напрямую войдите в него. Начните заполнять свою конфигурацию. 


Обратите внимание на часть рисования, это то, что необходимо настроить в программе, если этого не сделать, это определенно не будет succeed. 

Второй кувшинКонечно, вы настроите это и не сможете succeed, не спрашивайте меня почему. Без изображений говорить не о чем... 


Не думайте, что Qididi шучит, это правда, это должен быть порт 80, на самом деле это просто один веб-сайт с доменом. Porque все веб-сайты с доменами выходят из порта 80, продолжайте говорить о главном. 

Qididi告诉我们,使用微信账号,必须有一台服务器,然后配置我们发布的网站即可,请注意,token是自己设定的,这个不是自动生成的,自己设定。URL就是我们发布的网站名称。 

Третий кувшин,Если веб-сайт не публикуется, информация о конфигурации интерфейса永远无法配置成功, запомните, это永远。 

Безопасный домен интерфейса JS, пожалуйста, смотрите документацию (http://mp.weixin.qq.com/wiki/7/aaa137b55fb2e0456bf8dd9148dd613f.html). 

Цель безопасности домена JS интерфейса - это загрузка изображений, вызов интерфейса изображения WeChat и т.д., например, когда вам нужно использовать камеру или загрузить фото, в этом случае вам потребуется безопасный интерфейс JS. О详情暂不详细描述. 

В版本的 backstage微信公众账号测试账号, в таблице прав доступа к интерфейсу есть эта позиция, которая также должна быть настроена. Это не обязательная настройка, а этот интерфейс может получить часть информации о пользователе WeChat. Стоит отметить, что каждый ID, соответствующий каждому公众账号у, уникален, то есть, даже если не меняется инtranet веб-сайта, если меняется公众号, то данные微信公众号 в этот момент не могут быть совместимыми, это просто уникально для общественной учетной записи. 

Четвертый минус,}}При подаче заявки на веб-разрешение WeChat, здесь информация о пользователе веб-разрешения, сам по себе это не проблема, но проблема в том, что нет подсказки. 

Обратите внимание на URL здесь,Он должен быть без www, и после него не должно быть обратной косой чертыТаким образом, формат обратного вызова URL здесь - abc.com OK. Запомните этот формат, это необходимо. Хорошо, сервер временно таков, а теперь начнем с кода. 

Начнем с проверки на сервере. Это есть пример на официальном сайте, но это PHP, на самом деле это просто проверка случайного числа, а затем проверка значения в случае POST. Давайте сразу перейдем к коду 

 public ActionResult Index()
 {
 if (Request.HttpMethod.ToLower() == "post")
 {
 if (CheckSignature())//Проверка, прошла ли серверная проверка
 {
 GetMenuList();//Загрузка меню
 }
 else
 {
 Response.Write("<h1>Oh</h1><h2>Встретимся на Марсе!!!</h2>");
 Response.End();
 }
 }
 else
 {
 CheckWechat();
 }
 return View();
 }
 // <summary>
 /// Возврат случайного числа означает успешную проверку
 // </summary>
 private void CheckWechat()
 {
 if (string.IsNullOrEmpty(Request.QueryString["echoStr"]))
 {
 Response.Write("Сообщение не приходит от WeChat");
 Response.End();
 }
 string echoStr = Request.QueryString["echoStr"];
 if (CheckSignature())
 {
 Response.Write(echoStr);
 Response.End();
 }
 }
// <summary>
 /// Проверьте подпись WeChat
 // </summary>
 // <returns></returns>
 /// Сортируйте параметры token, timestamp, nonce в алфавитном порядке
 /// Соедините три параметра строк в одну строку и выполните шифрование sha1
 /// Разработчик может сравнить зашифрованную строку с signature, чтобы определить, что запрос исходит от WeChat.
 private bool CheckSignature()
 {
 string signature = Convert.ToString(Request["signature"]);
 string timestamp = Convert.ToString(Request["timestamp"]);
 string nonce = Convert.ToString(Request["nonce"]);
 string[] ArrTmp = { Token, timestamp, nonce };
 Array.Sort(ArrTmp); // Сортировка словаря 
 string tmpStr = string.Join("", ArrTmp);
 tmpStr = FormsAuthentication.HashPasswordForStoringInConfigFile(tmpStr, "SHA1");
 tmpStr = tmpStr.ToLower();
 if (tmpStr == signature)
 {
 return true;
 }
 else
 {
 return false;
 }
 }

Публичная платформа может определить меню, если у нее есть права доступа, но как только меню начинается, ручная редактировка меню не может быть использована, то есть, если сервер проверен, то необходимо использовать свой код. 

Мы вместе посмотрим на метод GetMenuList(), который на самом деле очень прост. Это просто JSON-строка в формате. Затем вызывается интерфейс WeChat. Public void GetMenuList()   

<em id="__mceDel"> { 
 string weixin1 = ""; 
 weixin1 = @" { 
 "button":[ 
 { 
 "type":"click", 
 "name":"你好!" 
 "key":"hello" 
 }, 
 { 
 "type":"view", 
 "name":"公司简介", 
 "url":"http://www.xnfhtech.com" 
 }, 
 { 
 "name":"产品介绍", 
 "sub_button":[ 
 { 
 "type":"click", 
 "name":"产品1", 
 "key":"p1" 
 }, 
 { 
 "type":"click", 
 "name":"产品2", 
 "key":"p2" 
 }] 
 }] }"; 
 string access_token = Tools.WA_GetAccess_Token.IsExistAccess_Token(); 
 string i = this.MenuCreate(menu, access_token); 
 Response.Write(i); 
 <br><br>
</em>
 public string MenuCreate(string MenuJson, string access_token)
 {
 JavaScriptSerializer Jss = new JavaScriptSerializer();
 string setMenuUrl = "https://api.weixin.qq.com/cgi-bin/menu/create?access_token={0}";
 setMenuUrl = string.Format(setMenuUrl, access_token); // 获取token、拼凑url
 string respText = WebRequestPostOrGet(setMenuUrl, MenuJson);
 Dictionary<string, object> respDic = (Dictionary<string, object>)Jss.DeserializeObject(respText);
 return respDic["errcode"].ToString(); // 返回0发布成功
 }
// <summary>
 /// Post/get 提交调用抓取
 // </summary>
 /// <param name="url">提交地址</param>
 /// <param name="param">参数</param>
 /// <returns>string</returns>
 public string WebRequestPostOrGet(string sUrl, string sParam)
 {
 byte[] bt = System.Text.Encoding.UTF8.GetBytes(sParam);
 Uri uriurl = new Uri(sUrl);
 HttpWebRequest req = (HttpWebRequest)HttpWebRequest.Create(uriurl); // HttpWebRequest req = (HttpWebRequest)HttpWebRequest.Create(url + (url.IndexOf("?") > -1 ? "" : "?") + param);
 req.Method = "Post";
 req.Timeout = 120 * 1000;
 req.ContentType = "application/x-www-form-urlencoded;";
 req.ContentLength = bt.Length;
 using (Stream reqStream = req.GetRequestStream()) // Использование using позволяет освободить память в разделе using
 {
 reqStream.Write(bt, 0, bt.Length);
 reqStream.Flush();
 }
 try
 {
 using (WebResponse res = req.GetResponse())
 {
 // Здесь обрабатывается полученное содержимое страницы
 Stream resStream = res.GetResponseStream();
 StreamReader resStreamReader = new StreamReader(resStream, System.Text.Encoding.UTF8);
 string resLine;
 System.Text.StringBuilder resStringBuilder = new System.Text.StringBuilder();
 while ((resLine = resStreamReader.ReadLine()) != null)
 {
  resStringBuilder.Append(resLine + System.Environment.NewLine);
 }
 resStream.Close();
 resStreamReader.Close();
 return resStringBuilder.ToString();
 }
 }
 catch (Exception ex)
 {
 return ex.Message; // Возвращает ошибку при ошибке URL
 }
 }

Хорошо, я сознаюсь, что я невежественный гурман, как снова появился access_token=IsExistAccess_Token();? Не спешите, малыш расскажет тебе.

Когда мы читаем документ, мы замечаем, что Access_Token здесь истекает каждые два часа. Этот метод заключается в том, чтобы автоматически получить его при истечении срока. 

Пятая проблемаЗдесь JSON-строка, то есть меню, которое нужно показать, я хочу, чтобы все использовали строчные буквы, если вы используете заглавные буквы, то, эй, хихикайте, искренне, это очень сложно, он скажет вам, что не используется кодировка UTF8, но на самом деле вы действительно кодировали, но все равно出错, поэтому лучше использовать строчные буквы, уф 

Продолжая говорить о двух часах автоматического получения, затем это можно сделать через MenuCreate (вызов интерфейса меню WeChat) и вывод. Вот код. 

// <summary>
/// Предотвращение изменения токена каждые два часа при каждом запросе
// </summary>
public class WA_GetAccess_Token
{
 public WA_GetAccess_Token()
 {
 }
 public static WAEntity.Access_token GetAccess_Token()
 {
 string url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid="+ ConfigurationManager.AppSettings["AppID"] + "&secret="+ ConfigurationManager.AppSettings["AppSecret"];
 Access_token entity = new Access_token();
 try
 {
 HttpWebRequest req = (HttpWebRequest)HttpWebRequest.Create(url);
 req.Method = "GET";
 using (WebResponse wr = req.GetResponse())
 {
 HttpWebResponse myResponse = (HttpWebResponse)req.GetResponse();
 StreamReader reader = new StreamReader(myResponse.GetResponseStream(), System.Text.Encoding.UTF8);
 string content = reader.ReadToEnd();
 Access_token token = new Access_token();
 token = JsonHelper.ParseFromJson<Access_token>(content);
 entity.access_token = token.access_token;
 entity.expires_in = token.expires_in;
 }
 }
 catch{ //запись в журнал}
 return entity;
 }
 // <summary> 
 /// Определяет, истек ли срок действия Access_Token на текущую дату. Если срок действия истек, возвращает новый Access_Token,否则 возвращает прежний Access_Token 
 // </summary> 
 /// <param name="datetime"></param> 
 // <returns></returns> 
 public static string IsExistAccess_Token()
 {
 try
 {
 string Token = string.Empty;
 DateTime YouXRQ;
 //Чтение данных из файла XML и их отображение
 string filepath = HttpContext.Current.Request.MapPath("~/XMLFile.xml");
 StreamReader str = new StreamReader(filepath, System.Text.Encoding.UTF8);
 XmlDocument xml = new XmlDocument();
 xml.Load(str);
 str.Close();
 str.Dispose();
 Token = xml.SelectSingleNode("xml").SelectSingleNode("Access_Token").InnerText;
 YouXRQ = Convert.ToDateTime(xml.SelectSingleNode("xml").SelectSingleNode("Access_YouXRQ").InnerText);
 if (DateTime.Now > YouXRQ)
 {
 DateTime _youxrq = DateTime.Now;
 WAEntity.Access_token mode = GetAccess_Token();
 xml.SelectSingleNode("xml").SelectSingleNode("Access_Token").InnerText = mode.access_token;
 _youxrq = _youxrq.AddSeconds(Convert.ToInt32(mode.expires_in));
 xml.SelectSingleNode("xml").SelectSingleNode("Access_YouXRQ").InnerText = _youxrq.ToString();
 xml.Save(filepath);
 Token = mode.access_token;
 }
 return Token;
 }
 catch (Exception ex)
 {
 return "";// Записать лог
 }
 }
}
public class Access_token
{
 public Access_token()
 { }
 public string access_token { get; set; }
 public string expires_in { get; set; }
}
public class JsonHelper
{
 // <summary> 
 // Создать Json формат 
 // </summary> 
 // <typeparam name="T"></typeparam> 
 // <param name="obj"></param> 
 // <returns></returns> 
 public static string GetJson<T>(T obj)
 {
 DataContractJsonSerializer json = new DataContractJsonSerializer(obj.GetType());
 using (MemoryStream stream = new MemoryStream())
 {
 json.WriteObject(stream, obj);
 string szJson = Encoding.UTF8.GetString(stream.ToArray()); return szJson;
 }
 }
 // <summary> 
 // Получить модель Json 
 // </summary> 
 // <typeparam name="T"></typeparam> 
 // <param name="szJson"></param> 
 // <returns></returns> 
 public static T ParseFromJson<T>(string szJson)
 {
 T obj = Activator.CreateInstance<T>();
 using (MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(szJson)))
 {
 DataContractJsonSerializer serializer = new DataContractJsonSerializer(obj.GetType());
 return (T)serializer.ReadObject(ms);
 }
 }
}

Прости, я снова не понял сути, что такое XMLFile.xml, хорошо, я на самом деле не хочу это говорить так прямо, лучше всего показать это кодом.

<?xml version="1.0" encoding="utf-8"?>
<xml>
 <Access_Token>Получение_TOKEN</Access_Token>
 <Access_YouXRQ>2015/9/12 17:56:31</Access_YouXRQ>
</xml>

Я уверен, что ты действительно не хочешь что-то сказать 

Хорошо, молча ел семечки,静静地看着你们继续,今天就先到这里,然后我们继续前进,已经五个坑了呀,宝宝心里苦呀。

Вот и все, что было в этой статье, надеюсь, это поможет вам в изучении, также希望大家多多支持呐喊教程。

Заявление: содержимое этой статьи взято из Интернета, авторские права принадлежат соответствующему владельцу, контент предоставлен пользователями Интернета, веб-сайт не имеет права собственности, не underwent редактирование вручную и не несет ответственности за соответствующие юридические вопросы. Если вы обнаружите подозрительное содержимое о нарушении авторских прав, пожалуйста, отправьте письмо по адресу: notice#oldtoolbag.com (во время отправки письма, пожалуйста, замените # на @) для сообщения о нарушении и предоставьте соответствующие доказательства. Если обнаружено, сайт немедленно удаляет подозреваемое содержимое, нарушающее авторские права.

Рекомендуется к просмотру