一个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。请注意,这只是一个简单的示例,实际应用中可能需要对加密算法和过期时间进行调整。

相关推荐
源代码•宸1 天前
Golang原理剖析(channel面试与分析)
开发语言·经验分享·后端·面试·golang·select·channel
moxiaoran57531 天前
Go语言中的泛型
golang
加油20191 天前
GO语言内存逃逸和GC机制
golang·内存管理·gc·内存逃逸
源代码•宸1 天前
Golang原理剖析(channel源码分析)
开发语言·后端·golang·select·channel·hchan·sudog
liuyunshengsir1 天前
golang Gin 框架下的大数据量 CSV 流式下载
开发语言·golang·gin
CHHC18801 天前
golang 项目依赖备份
开发语言·后端·golang
老蒋每日coding1 天前
AI智能体设计模式系列(八)—— 记忆管理模式
人工智能·设计模式·golang
且去填词2 天前
深入理解 GMP 模型:Go 高并发的基石
开发语言·后端·学习·算法·面试·golang·go
a程序小傲2 天前
京东Java面试被问:多活数据中心的流量调度和数据同步
java·开发语言·面试·职场和发展·golang·边缘计算
卜锦元2 天前
EchoChat搭建自己的音视频会议系统01-准备工作
c++·golang·uni-app·node.js·音视频