>  기사  >  위챗 애플릿  >  PHP WeChat 공개 계정 개발 전의 문제

PHP WeChat 공개 계정 개발 전의 문제

高洛峰
高洛峰원래의
2017-03-21 16:08:021447검색

이 기사에서는 주로 PHP WeChat 공개 계정 개발 전의 5가지 함정을 자세히 소개합니다. 관심 있는 친구는

WeChat 공개 계정 개발 문서(https: //mp.weixin.qq.com/wiki)

먼저 공개 플랫폼 계정이 있어야 합니다. 자, 피트 계획을 시작하겠습니다.

첫 번째 함정, 기업 계정이 없으면 개발을 할 수 없다고 생각하지 마세요. 테스트 계정을 신청하면 더 많은 인터페이스가 있습니다. 소위 구독 계정보다.

PHP WeChat 공개 계정 개발 전의 문제

백그라운드 관리에 들어간 후 개발자 도구를 클릭하면 공개 플랫폼 테스트 계정이 보이고, 바로 들어갈 수 있습니다. 자신만의 구성을 작성하기 시작하세요.

PHP WeChat 공개 계정 개발 전의 문제

PHP WeChat 공개 계정 개발 전의 문제

이 부분은 프로그램에서 반드시 설정해야 하는 부분입니다. 구성된 것은 확실히 성공하지 못할 것입니다.

두 번째 구덩이 물론 구성이 실패해야 합니다. 이유는 묻지 마세요. 몇 마디 말할 사진이 없어요. . .

PHP WeChat 공개 계정 개발 전의 문제

황제펭귄이 농담한다고 생각하지 마세요. 포트 80이겠죠. 사실은 그냥 도메인이 있는 웹사이트입니다. 이름. 도메인 이름 웹사이트는 모두 포트 80을 사용하지 않으므로 주제를 계속 진행하겠습니다.

펭귄왕께서 위챗 계정을 사용하려면 서버가 있어야 하고 우리가 게시하는 웹사이트를 구성해야 한다고 하더군요. 토큰은 자동으로 생성되지 않습니다. 위로. . URL은 우리가 게시하는 웹사이트의 이름입니다.

세 번째 함정은 웹사이트가 게시되지 않으면 인터페이스 구성 정보가 절대 구성되지 않는다는 것입니다. 영원히.

JS 인터페이스 보안 도메인 이름의 목적은 사진 다운로드, WeChat 사진 인터페이스 호출 등입니다. 예를 들어 카메라를 호출해야 하거나 사진을 업로드해야 할 때 JS 보안 인터페이스이므로 구체적인 내용은 당분간 자세히 설명하지 않습니다.

WeChat 공개 계정 테스트 계정 버전 배경에는 반드시 구성해야 하는 체험 인터페이스 권한 테이블이 있습니다. 구성할 필요는 없지만 이 인터페이스는 WeChat 사용자의 일부 정보를 얻을 수 있습니다. 각 공개 계정에 해당하는 각 ID는 고유하다는 점을 기억할 필요가 있습니다. 즉, 웹사이트의 인트라넷이 변경되지 않더라도 공개 계정이 변경되면 현재 WeChat 공개 계정의 데이터는 공유될 수 없습니다. . 공개 계정에 비해 상대적으로 독특할 뿐입니다.

PHP WeChat 공개 계정 개발 전의 문제

네 번째 구덩이 WeChat 웹페이지 승인 신청 시 승인된 웹페이지의 기본 정보는 다음과 같습니다. 사용자님, 이 자체로는 문제가 없으나 프롬프트가 없으면 문제가 있는 것입니다.

PHP WeChat 공개 계정 개발 전의 문제

여기 URL은 에 www가 포함되어서는 안 되며 백슬래시도 없어야 한다는 점에 유의하세요 , 즉 여기 URL의 콜백 형식은 abc.com입니다. 이 형식을 기억해 두십시오. 이렇게 해야 합니다. 좋아요, 일단은 서버를 이대로 두고 코드로 이야기를 시작하겠습니다.

먼저 서버 검증부터 시작하겠습니다. 공식 홈페이지에 이에 대한 예가 있지만 사실은 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;
 }
 }

그러면 퍼블릭 플랫폼에서 권한이 있으면 메뉴를 커스터마이징할 수 있지만, 일단 메뉴 커스터마이징을 시작하면 수동으로 편집한 원본 메뉴를 In할 수 없습니다. 즉, 서버 검증이 통과되면 자체 코드를 사용해 제어해야 합니다.

我们一起来看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 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.