Golang从Webview中获取Cookies的方法
Golang从Webview中获取Cookies的方法 我正在编写一个Go组件,并希望在启动时提供个人用户登录功能。理想情况下,这应该通过一个webview来完成,该webview在程序启动时被拉起。这个webview应该连接到一个独立于我的程序的身份服务器。如果登录成功,响应中会设置一个包含访问令牌和刷新令牌的cookie。此时,我希望webview关闭,并从cookie中提取令牌以供Go程序使用。
我曾尝试使用webview库zserge/webview来实现这一点。然而,我还没有找到使用这个库提取cookie的方法。内置库net/http具有检索cookie的功能——但是,zserge/webview库似乎没有使用内置的net/http库。
这可能实现吗?
更多关于Golang从Webview中获取Cookies的方法的实战教程也可以访问 https://www.itying.com/category-94-b0.html
或许开个问题去问问编写这个库的人。
更多关于Golang从Webview中获取Cookies的方法的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
在Go中从webview获取cookies确实是一个常见需求。对于zserge/webview库,由于它使用系统原生webview组件,无法直接访问cookies。不过可以通过JavaScript注入和本地HTTP服务器的方式实现。
以下是两种可行的解决方案:
方案1:使用JavaScript注入获取cookies
package main
import (
"fmt"
"log"
"net/http"
"time"
"github.com/zserge/webview"
)
func main() {
// 创建本地HTTP服务器来接收cookies
http.HandleFunc("/cookies", func(w http.ResponseWriter, r *http.Request) {
cookies := r.URL.Query()["cookie"]
for _, cookie := range cookies {
fmt.Printf("Received cookie: %s\n", cookie)
// 这里可以解析cookie并提取令牌
}
w.Write([]byte("OK"))
})
go http.ListenAndServe(":8080", nil)
// 创建webview
w := webview.New(webview.Settings{
Title: "登录",
URL: "https://your-auth-server.com/login",
Width: 800,
Height: 600,
ExternalInvokeCallback: func(w webview.WebView, data string) {
// 从JavaScript接收数据
fmt.Printf("Received from JS: %s\n", data)
// 这里可以处理cookies
w.Terminate()
},
})
// 注入JavaScript来监控登录成功和获取cookies
w.Init(`
// 监控登录成功
function checkLoginSuccess() {
// 根据你的登录页面实际情况调整这个条件
if (window.location.href.includes('login-success') ||
document.body.innerText.includes('登录成功')) {
// 获取所有cookies
var cookies = document.cookie;
// 发送到Go程序
external.invoke(cookies);
// 或者发送到本地服务器
fetch('http://localhost:8080/cookies?cookie=' + encodeURIComponent(cookies));
}
}
// 定期检查登录状态
setInterval(checkLoginSuccess, 1000);
// 或者监听页面变化
window.addEventListener('load', checkLoginSuccess);
`)
w.Run()
}
方案2:使用gowebview库(支持cookies访问)
package main
import (
"fmt"
"net/http"
"net/url"
"time"
"github.com/wailsapp/wails/v2/pkg/runtime"
"github.com/wailsapp/wails/v2"
)
type App struct {
ctx context.Context
}
func (a *App) startup(ctx context.Context) {
a.ctx = ctx
// 创建webview窗口
runtime.WindowExecJS(a.ctx, `
// 加载登录页面
window.location.href = 'https://your-auth-server.com/login';
// 监听页面加载完成
window.addEventListener('load', function() {
// 获取cookies
var cookies = document.cookie;
// 发送回Go
window.go.main.App.HandleCookies(cookies).then(() => {
// 关闭窗口
window.close();
});
});
`)
}
func (a *App) HandleCookies(cookies string) {
fmt.Printf("Received cookies: %s\n", cookies)
// 解析cookies
req := &http.Request{Header: http.Header{"Cookie": []string{cookies}}}
parsedCookies := req.Cookies()
for _, cookie := range parsedCookies {
fmt.Printf("Cookie: %s = %s\n", cookie.Name, cookie.Value)
// 提取访问令牌和刷新令牌
if cookie.Name == "access_token" {
// 保存访问令牌
}
if cookie.Name == "refresh_token" {
// 保存刷新令牌
}
}
}
func main() {
app := &App{}
err := wails.Run(&wails.AppConfig{
Width: 800,
Height: 600,
Title: "登录",
JS: "",
CSS: "",
Colour: "#131313",
Assets: wails.Assets{},
Bind: []interface{}{
app,
},
})
if err != nil {
fmt.Println("Error:", err)
}
}
方案3:使用自定义HTTP客户端和cookie jar
package main
import (
"fmt"
"net/http"
"net/http/cookiejar"
"net/url"
"time"
"github.com/zserge/webview"
)
func main() {
// 创建cookie jar来存储cookies
jar, _ := cookiejar.New(nil)
client := &http.Client{
Jar: jar,
Timeout: 30 * time.Second,
}
// 启动webview
w := webview.New(webview.Settings{
Title: "登录",
URL: "https://your-auth-server.com/login",
Width: 800,
Height: 600,
})
// 在webview关闭后,使用HTTP客户端访问相同URL获取cookies
w.Run()
// webview关闭后,使用相同的HTTP客户端访问页面获取cookies
resp, err := client.Get("https://your-auth-server.com/login")
if err == nil {
defer resp.Body.Close()
// 获取该URL的cookies
u, _ := url.Parse("https://your-auth-server.com")
cookies := jar.Cookies(u)
for _, cookie := range cookies {
fmt.Printf("Cookie: %s=%s\n", cookie.Name, cookie.Value)
}
}
}
方案4:使用Chrome DevTools Protocol(CDP)
package main
import (
"context"
"fmt"
"time"
"github.com/chromedp/chromedp"
)
func main() {
// 创建chrome实例
ctx, cancel := chromedp.NewContext(context.Background())
defer cancel()
// 设置超时
ctx, cancel = context.WithTimeout(ctx, 30*time.Second)
defer cancel()
var cookies string
// 运行任务
err := chromedp.Run(ctx,
// 导航到登录页面
chromedp.Navigate("https://your-auth-server.com/login"),
// 等待登录完成(根据实际情况调整选择器)
chromedp.WaitVisible("#login-success", chromedp.ByID),
// 获取cookies
chromedp.ActionFunc(func(ctx context.Context) error {
cookiesObj, err := chromedp.RunResponse(ctx,
chromedp.Tasks{
chromedp.Evaluate(`document.cookie`, &cookies),
},
)
if err != nil {
return err
}
// 也可以通过cookiesObj获取
fmt.Printf("Cookies from document: %s\n", cookies)
return nil
}),
)
if err != nil {
fmt.Printf("Error: %v\n", err)
}
// 解析和使用cookies
fmt.Printf("Final cookies: %s\n", cookies)
}
推荐使用方案1或方案4。方案1适用于简单的webview集成,方案4提供了更完整的浏览器控制能力。如果使用zserge/webview,方案1的JavaScript注入是最直接的实现方式。

