File size: 2,982 Bytes
0d5b03e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
<?php
namespace lib\wechat;

use Exception;

class WeWorkMsg

{
    private $token;
    private $crypt;

    public function __construct($token, $aeskey)

    {
        global $conf;
        $this->token = $token;
        $this->crypt = new WechatCrypt($aeskey);
    }

    //验证URL有效性
    public function verifyURL()

    {
        if (!$this->verifySignature($_GET['echostr'])) {
			exit('签名验证失败');
		}
        $msg = $this->crypt->decrypt($_GET['echostr']);
        if(!$msg) exit('消息解密失败');
        exit($msg);
    }

    //获取回调的消息内容
    public function getMessage()

    {
        $xml = file_get_contents('php://input');
        $arr = $this->xml2array($xml);
        if (!$arr) exit('消息体解析失败');
        if (!$this->verifySignature($arr['Encrypt'])) {
			exit('签名验证失败');
		}
        $msgtext = $this->crypt->decrypt($arr['Encrypt']);
        if(!$msgtext) exit('消息解密失败');
        $msg = $this->xml2array($msgtext);
        return $msg;
    }

    //响应消息内容
    public function responseMessage($array, $corpid)

    {
        $xml = $this->array2Xml($array);
        $encrypted = $this->crypt->encrypt($xml, $corpid);
        $timestamp = time();
        $nonce = time();
        $signature = $this->getSignature($timestamp, $nonce, $encrypted);
        $array = [
            'Encrypt' => $encrypted,
            'MsgSignature' => $signature,
            'TimeStamp' => $timestamp,
            'Nonce' => $nonce
        ];
        echo $this->array2Xml($array);
    }

    //验证回调签名
    private function verifySignature($msg_encrypt)

    {
        if (!(isset($_GET['msg_signature']) && isset($_GET['timestamp']) && isset($_GET['nonce']))) {
			return false;
		}

        $signature = $this->getSignature($_GET['timestamp'], $_GET['nonce'], $msg_encrypt);

		return $signature === $_GET['msg_signature'];
    }

    //生成SHA1签名
    private function getSignature($timestamp, $nonce, $encrypt_msg)

    {
        $signatureArray = array($encrypt_msg, $this->token, $timestamp, $nonce);
		sort($signatureArray, SORT_STRING);
        return sha1(implode($signatureArray));
    }

    //转为XML数据
    private function array2Xml($data)

    {
        if (!is_array($data)) {
            return false;
        }
        $xml = '<xml>';
        foreach ($data as $key => $val) {
            $xml .= (is_numeric($val) ? "<{$key}>{$val}</{$key}>" : "<{$key}><![CDATA[{$val}]]></{$key}>");
        }
        return $xml . '</xml>';
    }

    //解析XML数据
    private function xml2array($xml)

    {
        if (!$xml) {
            return false;
        }
		LIBXML_VERSION < 20900 && libxml_disable_entity_loader(true);
        return json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA), JSON_UNESCAPED_UNICODE), true);
    }
}