package main import ( "encoding/base64" "errors" "fmt" "io" "log/slog" "net/http" "net/url" "os" "strings" "resty.dev/v3" ) type loginCredentials struct { user string password string } // getLoginCookies 优先读取数据库中的 Cookie,未命中时执行登录并缓存新 Cookie。 func getLoginCookies(db *DB, client *resty.Client) ([]*http.Cookie, error) { cookies, err := db.GetCookie() if err == nil { return cookies, nil } if !errors.Is(err, errCookieNotFound) { return nil, err } credentials, err := loadLoginCredentials() if err != nil { return nil, err } cookies, err = login423Down(client, credentials) if err != nil { return nil, err } if len(cookies) == 0 { return cookies, nil } if err := db.SetCookie(cookies); err != nil { slog.Warn("failed to cache login cookies", slog.String("error", err.Error())) } return cookies, nil } // loadLoginCredentials 从环境变量读取 423down 登录账号。 func loadLoginCredentials() (loginCredentials, error) { credentials := loginCredentials{ user: strings.TrimSpace(os.Getenv(loginUserEnv)), password: os.Getenv(loginPasswordEnv), } if credentials.user == "" || credentials.password == "" { return loginCredentials{}, fmt.Errorf("missing login credentials: set %s and %s", loginUserEnv, loginPasswordEnv) } return credentials, nil } // login423Down 提交 WordPress 登录表单并返回登录态 Cookie。 func login423Down(client *resty.Client, credentials loginCredentials) ([]*http.Cookie, error) { form := url.Values{} form.Add("log", credentials.user) form.Add("pwd", credentials.password) form.Add("rememberme", "forever") form.Add("wp-submit", "登录") form.Add("testcookie", "1") resp, err := client.R(). SetHeader("Content-Type", "application/x-www-form-urlencoded"). SetBody(form.Encode()). Post(loginURL) if err != nil { return nil, fmt.Errorf("login request failed: %w", err) } defer func() { _ = resp.Body.Close() }() cookies := resp.Cookies() if hasWordPressLoggedInCookie(cookies) { return cookies, nil } body, err := io.ReadAll(resp.Body) if err != nil { return nil, fmt.Errorf("read login response failed: %w", err) } if canVisitLimitedPage(body) { return cookies, nil } return nil, errors.New("failed to get login cookies") } // hasWordPressLoggedInCookie 判断响应中是否包含 WordPress 登录态 Cookie。 func hasWordPressLoggedInCookie(cookies []*http.Cookie) bool { for _, cookie := range cookies { if strings.Contains(cookie.Name, "wordpress_logged_in") { return true } } return false } // canVisitLimitedPage 兼容源站可能返回明文或 base64 编码页面的情况。 func canVisitLimitedPage(body []byte) bool { if strings.Contains(string(body), "个人中心") { return true } decoded, err := base64.StdEncoding.DecodeString(string(body)) if err != nil { return false } return strings.Contains(string(decoded), "个人中心") }