在学习go语言的过程中,go语法确实有点怪怪的,然后看着一些简单学习代码,也学不下,没办法找点项目来搞搞,今天刚开的微信公众号,顺便也开了一下小程序,然后曾这今年25岁,赶紧又开了一把腾讯的学生服务器,需要的都准备好,接下来我们就开始实现微信公众号开发实战。
1.1 公众号设置
注册大家都知道在搜索微信公众号就可以了,开通一个订阅号,剩下的就按要求填写即可。
我们需要成为开发者,所以管理页面,往下拉,就可以看到开发:
之后又一个权限允许,允许了之后就可以看到权限列表,我们现在可以先浏览一下,不过基本的获取消息还是有权限的。
1.2 第一个服务器程序
开启了权限之后,我们要进行配置服务器,微信公众号的流程是这样的:
就是这么简单,微信公众平台就是使用http跟我们自己的服务器通信的,所以我们先写一个测试我们服务器的程序。
我们就用go语言来实现,也刚好正在学习go,之前用c/c++实现,真的是太难了,要不就直接用nginx,要不就自己手撕,手撕太累,所以要开发速度还是要用go。
go封装的太厉害,我们相用http的时候,算了,直接看程序把,在程序中注释
package main
import (
"fmt"
"net/http"
)
//http.ResponseWriter : 回复http的对应
//http.Request : http请求的对象
func sayHello(w http.ResponseWriter, r *http.Request) {
fmt.Println("http url ", r) //打印http的请求url
_, _ = w.Write([]byte("hello world") ) //这个就是往网页端输出的值
}
func main() {
fmt.Println("服务器程序")
http.HandleFunc("/", sayHello) // 匹配url的/就会调用sayHello
http.HandleFunc("/wx", sayHello) // 匹配url的/wx就会调用sayHello
err := http.ListenAndServe(":80", nil) //这个就是绑定服务器的80端口
if err != nil {
fmt.Println("ListenAndServer error", err)
}
}
功能比较简单,我们就来试试看看结果:
注意:绑定80端口需要管理员权限,我就试了很多次,发现竟然失败,那时候还没把错误打印出现,还以为端口占用了,一直查都没有被占用,无奈只能加错误打印,才看到权限不够
使用go run运行
我们看看结果:
这样就能访问到服务器了。
1.3 获取token
服务器测试完成之后,我们接下来进行配置服务器,让微信公众平台,跟服务器之间的通道建立起来。
打开基本配置信息,看到服务器配置,我这里还是没配置的,所以我也是第一次配置,比较喜欢一边写一边做笔记,这样写完了笔记也自然做完了,就跟写文档一样。
接下来点击修改配置,填写内容:
可以点击提交,但是会收到token验证失败,这时候肯定会失败,因为微信公众平台会发一个验证给我们的服务器,我们服务器需要也按照对应的逻辑给公众号平台回复,所以需要看一下公众号开发文档,看看这是什么协议:
1开启公众号开发者模式
微信官方给出的逻辑图,我们下面分步骤做:
- 尝试获取4个字段
- 赋值一个token
- token,timestamp,nonce按字典排序的字符串list
- 哈希算法加密list得到hashcode
- 判断hashcode是否等于signature
- 如果等于就返回echostr
如果不知道微信公众平台发过来的是什么参数,可以使用万能的打印方式,就可以看到微信公众平台发了啥:
这下子是不是就明白了,我们就把这4个字段提取回来,就可以完成第一步了。
接下来代码就是按7个步骤实现:
package main
import (
"fmt"
"net/http"
"sort"
"crypto/sha1"
)
const (
token = "xxxxx" //跟微信公众平台的token一样即可
)
//http.ResponseWriter : 回复http的对应
//http.Request : http请求的对象
func sayHello(w http.ResponseWriter, r *http.Request) {
fmt.Println("http url ", r) //打印http的请求url
defer r.Body.Close()
//1.尝试获取4个字段
nonce := r.URL.Query().Get("nonce")
timestamp := r.URL.Query().Get("timestamp")
signature := r.URL.Query().Get("signature")
echostr := r.URL.Query().Get("echostr")
// if nonce != nil && timestamp != nil && signature != nil && echostr != nil {
// fmt.Printf("字段提取成功")
// } else {
// return
// }
//2. 赋值一个token
//3.token,timestamp,nonce按字典排序的字符串list
strs := sort.StringSlice{token, timestamp, nonce} // 使用本地的token生成校验
sort.Strings(strs)
str := ""
for _, s := range strs {
str += s
}
// 4. 哈希算法加密list得到hashcode
h := sha1.New()
h.Write([]byte(str))
hashcode := fmt.Sprintf("%x", h.Sum(nil)) // h.Sum(nil) 做hash 79efadd80a344c0b73b3bd2c403184f7425a5a67
//5. 判断hashcode是否等于signature
fmt.Println("url once my_signature signature", nonce, hashcode, signature)
if hashcode != signature {
return
}
// 6. 如果等于就返回echostr
_, _ = w.Write([]byte(echostr) ) //这个就是往网页端输出的值
}
func main() {
fmt.Println("服务器程序")
http.HandleFunc("/", sayHello) // 匹配url的/就会调用sayHello
http.HandleFunc("/wx", sayHello) // 匹配url的/wx就会调用sayHello
err := http.ListenAndServe(":80", nil) //这个就是绑定服务器的80端口
if err != nil {
fmt.Println("ListenAndServer error", err)
}
}
是不是很简单,服务器后台运行了这个程序之后,我们就可以在微信公众平台点提交了,这样就可以看到提交成功。
成功的样子是这样的:
好像打码了也看不到,提交成功自己的可以看到了,不着急。