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

phpで微信公共アカウント開発の前五つの罠(一)

本題に入ります:

微信プラットフォームアカウント開発ドキュメント、公式版(https://mp.weixin.qq.com/wiki),信じてください、私はこのドキュメントを書いた人に苛立ちを感じていました、私は本当にこのキーボードを叩きつけたくなりましたが、実際に手を入れたら、これは自分でお金を払って買ったキーボードだと気づきました。。。。気まずいです。 

余計なことを言わずに、デプロイメントや開発方法について説明します。 

まず、あなたにはプラットフォームアカウントが必要です、それでは、穴を数えます。 

第1の穴企業アカウントでないからといって開発できないと考えてはいけません、テストアカウントを申請できます、これはサブスクライバーアカウントのインターフェースよりももっと多いです。

 

バックエンド管理にログインして、開発者ツールをクリックして、プラットフォームのテストアカウントが見えるので、直接そこに入ってください。自分の設定を開始します。 


落書き部分に注意してください、これはプログラムで設定する必要がある部分で、設定されていない場合は、これは必ず失敗します。 

第2の穴もちろん、あなたがこれのように設定しても成功する可能性は低いです。なぜかを聞かないでください。画像がなくて何も言えません。。 


企鹅帝は遊びでやっていると考えてはいけません、これは真実です、これは本当に80ポートは、実際には公開するドメインのウェブサイトだけで十分です。なぜなら、ドメインのウェブサイトはすべて80ポートから出てくる、続いて本題について話します。 

企鹅帝が教えてくれたように、微信アカウントを使用するには、サーバーがあり、公開するウェブサイトを設定する必要があります。注意してください、tokenは自分で設定されているので、これは自動生成されていない、自分で設定してください。。URLは公開するウェブサイトの名前です 

第3の穴ウェブサイトが公開されていない場合、インターフェース設定情報は常に設定できません。覚えておいてください、それは常にです。 

JSインターフェースセキュリティドメイン、これについてはドキュメント(http:)を直接参照してください//mp.weixin.qq.com/wiki/7/aaa137b55fb2e0456bf8dd9148dd613f.html)。 

JSインターフェースの安全ドメインの目的は、画像をダウンロードしたり、微信の画像インターフェースを呼び出したりするためです。例えば、カメラを呼び出す必要がある場合や、写真をアップロードする必要がある場合、この時はJS安全インターフェースが必要です。具体的な内容についてはここでは詳細に説明しません。 

微信公衆アカウントのテストアカウントのバックエンドに、体験インターフェース権限テーブルの中のこの項目も設定する必要があります。これは必ずしも設定する必要はありませんが、このインターフェースは微信ユーザーの一部の情報を取得できます。注意すべきは、各公衆アカウントに対応する各IDがユニークであることです。つまり、サイトの内網が変わらなくても、公衆アカウントが変わると、この時の微信公衆アカウントのデータは共有できません。これは相対的に公衆アカウントがユニークであることを意味します。 

第四の問題点、微信のウェブページ認証を申請する際に、ここの場所のウェブページ認証ユーザーの基本情報は問題ありませんが、警告が無いと問題があります。 

ここの場所の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の三つのパラメータを辞書順に並べ替えます
 /// 三つのパラメータの文字列を結合してshaの文字列にします1暗号化
 /// 開発者が暗号化された文字列を取得し、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, "SHA"1");
 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":"p"1"" 
 }, 
 { 
 "type":"click" 
 "name":"产品"2", 
 "key":"p"2"" 
 } 
 }] }"; 
 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();
 resStringBuilder.ToString()を返します。
 }
 }
 catch (Exception ex)
 {
 ex.Messageを返します。//URLが間違っている場合、エラーメッセージが返されます。
 }
 }

いいえ、私は自分が真相を知らない食いしりです。どうしてaccess_token=IsExistAccess_Token();がまた一つ増えたのでしょうか?焦らず、お話ししましょう。

ドキュメントを読んでいるとき、ここのAccess_Tokenが2時間ごとに期限切れになることを発見します。その方法は、期限切れになったときに自動的に取得することです。 

第五坑,这里的JSON字符串,也就是要展示的菜单,我希望大家都用小写,如果用了大写,那么,呵呵,哈哈了真心的,很操蛋的,他会告诉你没有用UTF88编码,但是你真心是编码过的,可惜还是出错,所以,还是小写吧,唉 

继续说两个小时自动获取之后,就是通过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#63;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);8);
 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>トークンを取得</Access_Token>
 <Access_YouXRQ>2015/9/12 17:56:31</Access_YouXRQ>
</xml>

あなたは本当に何も言いたくないですね。 

もういい加減に、静かにお菓子を食べて、皆さんが続けるのを見ています。今日はここまでにしておきましょう。後でまた進みましょう。すでに5つの穴がありますよ。子供の心は苦しいです。

これで本文のすべての内容が終わりました。皆さんの学習に役立つことを願っています。また、呐喊トレーニングのサポートを多くいただければ幸いです。

声明:本文の内容はインターネットから収集され、著作権者によるものです。インターネットユーザーにより自発的に提供された内容であり、本サイトは所有権を持ちません。人工的な編集は行われていません。また、関連する法的責任を負いません。著作権に問題があると感じる場合は、メールを送信してください:notice#oldtoolbag.com(メールを送信する際は、#を@に置き換えてください。告発を行い、関連する証拠を提供してください。一旦確認がつき次第、本サイトは侵害される内容をすぐに削除します。)

おすすめ