微信很棒,Golang也很棒,我有一个小打算,用微信来控制我司的智能家居面板开关等等东东。刚好也在学习Golang,就拿它来练练手。
微信规定了接入的接口必须是80端口的Http服务,每个发往公共账号的消息,微信平台都会通过Post方式丢到约定好的接口上,URL如下
http://www.wadahana.com/weixin.goapp?signature=41a1e2aec5e0bb6b8686ee361e5b305cf5c04f13&echostr=1000737891698810841×tamp=1407852505&nonce=1183067877
我们所需要做的signature check就是简单的把timestamp,nonce 和在weixin平台上提交的token做字符排序,然后拼接在一起,直接拿来做sha, 如果和signature相等,则表明这条Post请求是由微信平台丢过来的,不相等的话,就不知道是哪个阿猫阿狗搞来的了,验证成功的话,把echostr的内容原封不动发给微信平台即可。
然后,我们就上代码就好了.
func weixinHandler( w http.ResponseWriter,r *http.Request ){
path := r.URL.Path[1:]
fmt.Printf("Path : %s\r\n", path);
httpRequestDump(r);
r.ParseForm();
if len( r.Form ) > 0 {
for key, vals := range r.Form{
fmt.Printf("<%s: %s>\r\n", key, vals[0]);
}
}
bRet := checkSignature( r.Form );
if bRet {
fmt.Println("check signature success");
fmt.Fprintf(w, r.Form.Get("echostr"));
}else{
fmt.Printf("check signature fail");
}
}
func checkSignature(values url.Values) bool {
array := []string{ values.Get("nonce"), values.Get("timestamp"), token }; // token 为微信开发者平台上提交的字符串
sort.Sort( sort.StringSlice(array) );
tmpStr := string(array[0] + array[1] + array[2]);
data := []byte( tmpStr );
hash := sha1.Sum(data);
chkStr := hex.EncodeToString( hash[0:20] );
if chkStr != values.Get("signature"){
return false;
}
return true;
}