查看原文观看视频:http://www.ibloger.net/article/272.html
官方PHP接入文件注释介绍
<?php
/**
* wechat php test 表明php语句的说明和开始,表示此为php语言
*/
// 定义 token
define("TOKEN", "weixin");
$wechatObj = new wechatCallbackapiTest(); // 实例化当前class类
$wechatObj->valid(); // $webchatObj变量—>访问类中valid()方法
class wechatCallbackapiTest // 定义一个类,类名是class后的内容
{
public function valid() // 定义一个共有的名为valid的方法
{
$echoStr = $_GET["echostr"]; // 从微信用户获取一个随机变量$echoStr
//验证签名signature , 可选
if($this->checkSignature()){
echo $echoStr; // 如果签名相同,输出$echostr变量
exit;
}
}
public function responseMsg() // 以下是一个公有的responseMsg的方法,是这段代码的核心内容,获得微信用户段发来的信息,不同环境有所不同
{
//get post 数据, 可能是由于不同的环境
$postStr = $GLOBALS["HTTP_RAW_POST_DATA"]; // 将信息保存到变量$postStr中,同时解析用户数据
//提取post数据
if (!empty($postStr)){ // 如果用户端数据不为空
/* libxml_disable_entity_loader是防止XML外部实体注入,最好的办法就是自己检查XML的有效性 */
libxml_disable_entity_loader(true);
$postObj = simplexml_load_string($postStr, 'SimpleXMLElement', LIBXML_NOCDATA); // 将变量$postStr解析并赋予变量$postObj
$fromUsername = $postObj->FromUserName; // 将用户端的用户名赋予变量$fromUsername
$toUsername = $postObj->ToUserName; // 将公众号ID赋予变量$toUsername
$keyword = trim($postObj->Content); // 将发来的文本内容去空格后赋予变量$keyword
$time = time(); // 将系统时间赋予变量$time
// 构建XML格式的文本赋予变量$textTp1(ToUserName:微信目标方,FromUserName:微信来远方,CreateTime:系统时间,MsgType:回复微信信息类型,Content:回复微信内容,FuncFlag:是否为星标微信)
$textTpl = "<xml>
<ToUserName><![CDATA[%s]]></ToUserName>
<FromUserName><![CDATA[%s]]></FromUserName>
<CreateTime>%s</CreateTime>
<MsgType><![CDATA[%s]]></MsgType>
<Content><![CDATA[%s]]></Content>
<FuncFlag>0</FuncFlag>
</xml>";
if(!empty( $keyword )) { // 如果用户端发来的消息不是空
$msgType = "text"; // 回复文本消息为text文本类型
$contentStr = "欢迎来到 wechat 世界!"; // 这行就是我们进行文本回复的内容,如果要改回复的消息,只要在这里更改就可以
$resultStr = sprintf($textTpl, $fromUsername, $toUsername, $time, $msgType, $contentStr); // 将XML格式中的变量分别赋值,
echo $resultStr; // 输出回复消息
}else{
echo "Input something..."; // 输入内容,此消息不会发送到微信端,只是测试时候使用
}
}else {
echo "";
exit;
}
}
private function checkSignature() // 建立私有方法验证签名
{
// 你必须定义一个自己的TOKEN
if (!defined("TOKEN")) {
throw new Exception('TOKEN 未定义!');
}
$signature = $_GET["signature"]; // 从用户端获取签名赋予变量$signature
$timestamp = $_GET["timestamp"]; // 从用户段获取时间赋予变量$timestamp
$nonce = $_GET["nonce"]; // 从用户段获取随机数赋予变量$snonce
$token = TOKEN; // 将常量TOKEN值赋予变量$token
$tmpArr = array($token, $timestamp, $nonce); // 建立数组变量$tmpArr
sort($tmpArr, SORT_STRING); // 数组排序
$tmpStr = implode( $tmpArr ); // 字典排序
$tmpStr = sha1( $tmpStr ); // 加密
if( $tmpStr == $signature ){ // 判断$tmpStr与$signature变量是否同值
return true;
}else{
return false;
}
}
}
?>
接下来使用Java版本接入
微信请求校验类
package cn.weixin.validationTest;
import java.security.MessageDigest;
import java.util.Arrays;
/**
* 微信请求校验工具类
* @author X-rapido
* @version 1.0
*/
public class ValidationUtil{
private static String token="Rapido"; // 用户Token
/**
* 验证签名
*/
public static boolean checkSignauer(String signature,String timestamp,String nonce){
// 构建成一个字符串数组
String [] str = new String[]{token,timestamp,nonce};
Arrays.sort(str); // 排序
StringBuffer buff = new StringBuffer();
for (int i = 0; i < str.length; i++) {
buff.append(str[i]);
}
MessageDigest md = null; // 加密类
String result = null;
try {
md = MessageDigest.getInstance("SHA-1"); // 实例加密算法(微信文档中用SHA-1)
byte[] digest = md.digest(buff.toString().getBytes());
result = bytesToStr(digest);
System.out.println("加密以后的字符串:"+result);
} catch (Exception e) {
e.printStackTrace();
}
return result != null? result.equals(signature.toUpperCase()) : false;
}
/**
* 将字节数组转换为16进制字符串
* @param byteArray
* @return
*/
private static String bytesToStr(byte[] byteArray){
String strDigest = "";
for (int i = 0; i < byteArray.length; i++) {
strDigest += byteToHexStr(byteArray[i]);
}
return strDigest;
}
/**
* 将一个字节转换为16进制字符串
* @param mByte
* @return
*/
private static String byteToHexStr(byte mByte){
char [] digit={'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
char [] temp = new char[2];
temp[0] = digit[(mByte>>>4) & 0X0F];
temp[1] = digit[mByte & 0X0F];
String s = new String(temp);
return s;
}
}
微信测试接入类
package cn.weixin.servlet;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import cn.weixin.common.ValidationUtil;
/**
* 接收来自微信服务器转发过来的请求[验证消息真实性]
*
* @author X-rapido
*
*/
public class AccessVerifyServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String signature = request.getParameter("signature"); // 获取微信加密的签名字符串
String timestamp = request.getParameter("timestamp"); // 时间戳
String nonce = request.getParameter("nonce"); // 随机数
String echostr = request.getParameter("echostr"); // 随机字符串
System.out.println("加密的签名串signatur:"+signature+",时间戳timestamp:"+timestamp+",随机数nonce:"+nonce+",随机字符串echostr:"+echostr);
PrintWriter out = response.getWriter();
if(ValidationUtil.checkSignauer(signature, timestamp, nonce)){
out.print(echostr);
}
out.close();
}
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
<display-name>weixin</display-name>
<distributable/>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<servlet>
<description>微信接入验证</description>
<servlet-name>AccessVerifyServlet</servlet-name>
<servlet-class>cn.weixin.servlet.AccessVerifyServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>AccessVerifyServlet</servlet-name>
<url-pattern>/AccessVerifyServlet</url-pattern>
</servlet-mapping>
</web-app>
在一下联接中使用
微信在接入时候,会以get数据请求我的url地址,我的Servlet就会接收数据,并进行签名认证返回接收的随机数,微信服务器接收随机数并进行签名认证,确定后就接入成功!