网易云API Golang版开发历程
原项目(node.js) 网易云音乐 API
本项目 (golang) 网易云音乐 API
api文档
请不要用于商业用途
想法的开始
事情的开始还是一开始在B站上看到了一个仿网易云网页版的VUE项目,当时挺喜欢的就fork了一下,打算继续完善这个项目就当Vue项目练手了,当时以为整个项目是有后端的,后来仔细一看发现是用了网易云音乐 API这个node项目伪造请求向网易云请求数据。后来稍微看了一下这个项目,虽然我不会用node但是好歹我也是会百度的,大概还是看出了核心代码(如何伪造请求)在哪里,感觉应该也不是太难,就打算巩固一下golang就想用golang实现一下。
解析原项目
说来丢人,看不懂node是如何接受请求的,没看到在哪定义了路由,十分疑惑(虽然并不影响我)。首先项目基本逻辑:
- 接受客户端请求
- 预处理:放行请求,允许跨域,拿出cookie(app.js)
- 构造伪请求,封装必要数据(module,util/request.js)
- 将数据进行加密,构造特定的请求参数(util/crypto.js)
- 向网易云发送请求(util/request.js)
- 解析返回数据,将数据返回给客户端,对于登录请求,还要写入cookie
整体的流程还是很好理解的,整个项目的重点在于util/request.js
,util/crypto.js
这两个包,一个负责发请求,一个负责加密。
构建golang项目
项目采用gin来处理路由,以singo为脚手架快速搭建web应用程序,采用asmcos/requests 发送请求。
重点代码
1.请求数据封装传递
// 邮箱登录接口为例
// 将客户端发送的请求绑定到结构体中
type LoginEmailService struct {
Email string `json:"email" form:"email"`
Password string `json:"password" form:"password"`
Md5password string `json:"md5_password" form:"md5_password"`
}
func (service *LoginEmailService) LoginEmail(c *gin.Context) map[string]interface{
} {
// 获得客户端请求的所有cookie
cookies := c.Request.Cookies()
// 因为这个请求需要这个cookie 故添加一个
cookiesOS := &http.Cookie{
Name: "os", Value: "pc"}
cookies = append(cookies, cookiesOS)
// 构建请求参数,util.Options为请求选项的封装,对应原项目的 options
options := &util.Options{
Crypto: "weapi",
Ua: "pc",
Cookies: cookies,
}
// data为请求的body的所需原数据
data := make(map[string]string)
data["username"] = service.Email
if service.Password != "" {
// 密码进行MD5
h := md5.New()
h.Write([]byte(service.Password))
data["password"] = hex.EncodeToString(h.Sum(nil))
} else {
data["password"] = service.Md5password
}
data["rememberLogin"] = "true"
// 将数据发往request 包括 请求方法,连接,数据,请求选项 返回网易云的数据返回和set-cookie
reBody, cookies := util.CreateRequest("POST", `https://music.163.com/weapi/login`, data, options)
cookiesStr := ""
for _, cookie := range cookies {
if cookiesStr != "" {
cookiesStr = cookiesStr + ";"
}
cookiesStr = cookiesStr + cookie.String()
// 写入cookie
c.SetCookie(cookie.Name, cookie.Value, 60*60