From a37368ddcfaf3e79329c452a4622bd56cb445b91 Mon Sep 17 00:00:00 2001 From: sugarBecomer Date: Fri, 14 Nov 2025 20:38:58 +0800 Subject: [PATCH] =?UTF-8?q?:sparkles:=20=E6=96=B0=E5=A2=9E=E9=80=82?= =?UTF-8?q?=E9=85=8D=E5=B1=B1=E4=B8=9C=E5=8D=8E=E5=AE=87=E5=B7=A5=E5=AD=A6?= =?UTF-8?q?=E9=99=A2=E6=BB=91=E5=9D=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- internal/application/cookiejar/jar.go | 63 ++++++++++++++++++++++- internal/application/cpdaily/login/cas.go | 4 +- main.go | 1 + 3 files changed, 65 insertions(+), 3 deletions(-) diff --git a/internal/application/cookiejar/jar.go b/internal/application/cookiejar/jar.go index adabc47..5cb9e6a 100644 --- a/internal/application/cookiejar/jar.go +++ b/internal/application/cookiejar/jar.go @@ -3,17 +3,47 @@ package cookiejar import ( "bytes" "encoding/gob" + "fmt" "github.com/bytedance/sonic" "io" "likedream-goframe/internal/utils" "net/http" "net/url" + "strings" "sync" ) type hostMap map[string]cookieMap type cookieMap map[string]*http.Cookie + +// cookieKey 生成 cookie 的唯一标识 key,使用 name 和 path 的组合 +func cookieKey(name, path string) string { + return fmt.Sprintf("%s|%s", name, path) +} + +// pathMatch 检查请求路径是否匹配 cookie 的 path +// 根据 RFC 6265 Section 5.1.4 +func pathMatch(requestPath, cookiePath string) bool { + // 如果路径完全相同 + if requestPath == cookiePath { + return true + } + + // 如果 cookie path 是请求 path 的前缀 + if strings.HasPrefix(requestPath, cookiePath) { + // cookie path 以 / 结尾,或者请求 path 在 cookie path 后紧跟 / + if strings.HasSuffix(cookiePath, "/") { + return true + } + if len(requestPath) > len(cookiePath) && requestPath[len(cookiePath)] == '/' { + return true + } + } + + return false +} + type PersistCookieJar struct { hostMap hostMap *sync.RWMutex @@ -40,7 +70,23 @@ func (p *PersistCookieJar) SetCookies(u *url.URL, cookies []*http.Cookie) { if p.hostMap[host] == nil { p.hostMap[host] = make(cookieMap) } - p.hostMap[host][cookie.Name] = cookie + + // 如果 cookie 没有设置 Path,使用默认值 "/" + cookiePath := cookie.Path + if cookiePath == "" { + cookiePath = "/" + } + + // 使用 name 和 path 的组合作为 key + key := cookieKey(cookie.Name, cookiePath) + + // 如果 MaxAge=0 或 MaxAge<0,表示删除 cookie + // 只删除完全匹配的 cookie(name 和 path 都相同) + if cookie.MaxAge < 0 || (cookie.MaxAge == 0 && cookie.Value == "") { + delete(p.hostMap[host], key) + } else { + p.hostMap[host][key] = cookie + } } } @@ -50,10 +96,23 @@ func (p *PersistCookieJar) Cookies(u *url.URL) []*http.Cookie { defer p.RUnlock() host := u.Host + requestPath := u.Path + if requestPath == "" { + requestPath = "/" + } + if cookies, exists := p.hostMap[host]; exists { result := make([]*http.Cookie, 0, len(cookies)) for _, cookie := range cookies { - result = append(result, cookie) + // 检查 cookie 的 path 是否匹配请求的 path + cookiePath := cookie.Path + if cookiePath == "" { + cookiePath = "/" + } + + if pathMatch(requestPath, cookiePath) { + result = append(result, cookie) + } } return result } diff --git a/internal/application/cpdaily/login/cas.go b/internal/application/cpdaily/login/cas.go index ae98b7b..347cbf9 100644 --- a/internal/application/cpdaily/login/cas.go +++ b/internal/application/cpdaily/login/cas.go @@ -190,7 +190,9 @@ func (c *CpdailyCasLogin) Login(ctx context.Context, schoolDetail *school.School } else { allInputs["password"] = encryptCasPassword(password, salt) } - var SliderCaptchaIds = []string{"1018764144934965"} + + // 声明需要滑块验证码的学校id + var SliderCaptchaIds = []string{"1018764144934965", "sdhyxy"} // 判断是否需要验证码 if isCasNeedCaptcha(ctx, loginResponseUrl, loginType, username, c.client) { // 如果是滑块验证码 diff --git a/main.go b/main.go index 5b4d6bb..8849ed8 100644 --- a/main.go +++ b/main.go @@ -22,6 +22,7 @@ func main() { if err != nil { log.Panic(err) } + time.Local = cst.TimeZoneShangHai args := "" if len(os.Args) > 1 { args = os.Args[1]