一个tiktok公开下载器的方案

文章目录

需求背景

实现一个可以下载无水印tiktok公开视频的功能

The TikTok URL link looks like this:

https://vm.tiktok.com/ZSJmdax66/

https://v.douyin.com/RKqEJBV

https://www.tiktok.com/@philandmore/video/6805867805452324102

https://m.tiktok.com/v/6805867805452324102.html

方案

1 py爬虫接口返回视频id

2.1 调用 music.ly 获取下载视频地址信息,直接返回

2.2 或者 http请求来下载文件,返回文件流

第三方公开接口

musical.ly接口直接获取浏览器可下载的接口,只支持tiktok链接,不支持doiuyin

GET\] https://api19-core-c-useast1a.musical.ly/aweme/v1/feed/?aweme_id=7257420363305323794 ## 转流的示例代码 视频链接下载走服务器流量,传文件流给前端 ```go func (m *FileBiz) DownloadFileV2(ctx *ctrl.Context, fileLink, fileName string) (err error) { // 记录下载日志 record.BusinessLog(record.Debug, "RecordDownloadFileV2", fmt.Sprintf("filePath:%s,wsId:%s,email:%s", fileLink, ctx.GetString("ws_id"), ctx.GetString("email")), "") // 获取地址异常 if fileLink == "" { err = errInfo.ErrFilesNull return } // 初始化 request, err := http.NewRequest("GET", fileLink, nil) if err != nil { record.BusinessLog(record.Error, "NewRequest", fmt.Sprintf("filePath:%s", fileLink), err.Error()) err = errInfo.ErrHttpInit return } // 执行请求 clt := http.Client{} resp, err := clt.Do(request) if err != nil { record.BusinessLog(record.Error, "HttpDp", fmt.Sprintf("filePath:%s", fileLink), err.Error()) err = errInfo.ErrHttpDo return } defer func(Body io.ReadCloser) { errClose := Body.Close() if errClose != nil { record.BusinessLog(record.Error, "FileClose", fmt.Sprintf("filePath:%s", fileLink), errClose.Error()) } }(resp.Body) // 响应头 ctx.Header("Content-Length", resp.Header.Get("Content-Length")) ctx.Header("Content-Disposition", fmt.Sprintf("attachment; filename=\"%s\"", fileName)) ctx.Header("Content-Type", "application/octet-stream;charset=UTF-8") ctx.Header("Set-Cookie", "download=success; Domain=.media.io; Path=/;") // 响应流 written, err := io.Copy(ctx.ResponseWriter(), resp.Body) if err != nil { record.BusinessLog(record.Error, "IoCopy", fmt.Sprintf("filePath:%s, written:%d", fileLink, written), err.Error()) err = errInfo.ErrResponseWritten } return } ``` ## 下载地址的密钥校验 为了实现这个需求,你需要在前端和后端之间建立一个认证机制。这里是一个简单的实现方法: 1. 前端和后端约定一个密钥(secret key),并确保只有它们知道这个密钥。 2. 前端在发起请求时生成一个有时效性的key(例如,使用Unix时间戳),并将其与密钥一起使用某种方式(例如,HMAC)进行加密,生成一个签名。 3. 前端将生成的key和签名一起作为请求头发送给后端。 4. 后端收到请求后,从请求头中获取key和签名,然后使用相同的加密方法对key和密钥进行加密,与请求头中的签名进行比较。 5. 如果签名匹配,检查key是否过期,如果未过期,则接受请求,否则拒绝请求。如果签名不匹配或请求头中的refer与期望的不匹配,拒绝请求。 结果:最后没有使用前端生成的code,还是后端传code,在单独的服务器上做验证和转流,避免影响主服务 PS:**永远不要相信前端传的数据,尽量数据校验都放在后端** 以下是一个简单的Go实现示例: ```go package main import ( "crypto/hmac" "crypto/sha256" "encoding/hex" "fmt" "net/http" "strconv" "time" ) const secretKey = "your-secret-key" const keyExpiration = 60 // Key expiration time in seconds func main() { http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { key := r.Header.Get("X-Key") signature := r.Header.Get("X-Signature") referer := r.Header.Get("Referer") // Check referer if referer != "your-expected-referer" { http.Error(w, "Forbidden", http.StatusForbidden) return } // Check key and signature if isValidKey(key, signature) { fmt.Fprintln(w, "Welcome!") } else { http.Error(w, "Forbidden", http.StatusForbidden) } }) http.ListenAndServe(":8080", nil) } func isValidKey(key, signature string) bool { // Check key expiration keyTime, err := strconv.ParseInt(key, 10, 64) if err != nil { return false } if time.Now().Unix()-keyTime > keyExpiration { return false } // Check signature mac := hmac.New(sha256.New, []byte(secretKey)) mac.Write([]byte(key)) expectedSignature := hex.EncodeToString(mac.Sum(nil)) return hmac.Equal([]byte(signature), []byte(expectedSignature)) } ``` 这个示例中,后端服务器会检查请求头中的Referer(请求的来源)、有时效性的X-Key和X-Signature。请注意,这只是一个简单的示例,实际应用中可能需要对加密算法和过期时间进行调整。

相关推荐
Go高并发架构_王工12 分钟前
基于 GoFrame 框架的电子邮件发送实践:优势、特色与经验分享
网络·经验分享·golang
Chandler2431 分钟前
Go:接口
开发语言·后端·golang
ErizJ33 分钟前
Golang|Channel 相关用法理解
开发语言·后端·golang
automan0233 分钟前
golang 在windows 系统的交叉编译
开发语言·后端·golang
Pandaconda33 分钟前
【新人系列】Golang 入门(十三):结构体 - 下
后端·golang·go·方法·结构体·后端开发·值传递
LuckyLay2 小时前
LeetCode算法题(Go语言实现)_46
算法·leetcode·golang
ErizJ4 小时前
Golang|协程
golang·协程·gmp
why1514 小时前
腾讯云golang一面
开发语言·后端·golang
TDengine (老段)6 小时前
TDengine 语言连接器(Go)
大数据·数据库·物联网·golang·时序数据库·tdengine·iotdb