この記事では主にphp WeChatパブリックアカウント開発前の5つの落とし穴を詳しく紹介します。興味のある友人は参考にしてください。
WeChatパブリックアカウント開発ドキュメント、正式版(https://mp.weixin.qq. com/wiki)
まず、パブリック プラットフォーム アカウントを持っている必要があります。それでは、トラップの計画を始めましょう。
最初の落とし穴、エンタープライズアカウントがなければ開発できないと考えないでください。テストアカウントを申請することができ、いわゆるサブスクリプションアカウントよりも多くのインターフェイスがあります。
バックグラウンド管理に入った後、開発者ツールをクリックすると、パブリックプラットフォームのテストアカウントが表示され、直接入力できます。独自の構成の入力を開始します。
この部分はプログラム内で設定する必要があるので、設定しないと必ず失敗します。
2 番目のピット、もちろん、設定は失敗しているはずです。理由は聞かないでください。一言言えるほどの写真はありません。 。 。
皇帝ペンギンが冗談を言っているとは思わないでください。これは本当です。実際には、それはドメイン名を持つ単なる Web サイトです。ドメイン名 Web サイトはすべてポート 80 から出力されているため、このトピックを続けましょう。
皇帝ペンギンは、WeChat アカウントを使用するには、サーバーを用意してから、公開する Web サイトを設定する必要があると教えてくれました。トークンは自分で設定するものではなく、自分で設定する必要があります。 。 URL は、私たちが公開する Web サイトの名前です
3 番目の落とし穴は、 Web サイトが公開されないと、インターフェース構成情報を永久に構成できないことです。
JS インターフェースの安全なドメイン名の目的は、写真をダウンロードしたり、WeChat の写真インターフェースを呼び出したりすることです。たとえば、カメラを呼び出す必要がある場合、または写真をアップロードする必要がある場合、現時点では JS 安全なインターフェースが必要です。具体的な内容についてはまだ詳しく説明しません。
WeChat パブリック アカウント テスト アカウントのバージョン バックグラウンドには、設定する必要があるエクスペリエンス インターフェイス権限テーブルがあります。設定する必要はありませんが、このインターフェイスは WeChat ユーザーの一部の情報を取得できます。各パブリックアカウントに対応する各IDは一意であること、つまり、Webサイトのイントラネットが変更されていない場合でも、パブリックアカウントが変更されると、その時点のWeChatパブリックアカウントのデータを共有することができないことに注意してください。 これはパブリック アカウントに比較的固有なだけです。
4 番目のピット、 WeChat Web ページの承認を申請する場合、Web ページ上の承認されたユーザーの基本情報がここに表示されます。これ自体は問題ありませんが、プロンプトが表示されない場合は問題があります。
ここの 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("消息并非来自微信"); Response.End(); } string echoStr = Request.QueryString["echoStr"]; if (CheckSignature()) { Response.Write(echoStr); Response.End(); } } /// <summary> /// 验证微信签名 /// </summary> /// <returns></returns> /// 将token、timestamp、nonce三个参数进行字典序排序 /// 将三个参数字符串拼接成一个字符串进行sha1加密 /// 开发者获得加密后的字符串可与signature对比,标识该请求来源于微信。 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格式字符串。然后调用微信的接口即可。 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(调用微信菜单接口)输出即可。上代码。
/// <summary> /// 防止每次请求的token两个小时的变化 /// </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的Model /// </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>
以上がPHP WeChatパブリックアカウント開発以前の問題の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。