1. 程式人生 > >GoLang實現 weixin 接入的驗證介面

GoLang實現 weixin 接入的驗證介面

微信很棒,Golang也很棒,我有一個小打算,用微信來控制我司的智慧家居面板開關等等東東。剛好也在學習Golang,就拿它來練練手。

微信規定了接入的介面必須是80埠的Http服務,每個發往公共賬號的訊息,微信平臺都會通過Post方式丟到約定好的介面上,URL如下

http://www.wadahana.com/weixin.goapp?signature=41a1e2aec5e0bb6b8686ee361e5b305cf5c04f13&echostr=1000737891698810841&timestamp=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;                                                                                                                    
}