🐛 修复短信登录
This commit is contained in:
@@ -48,22 +48,8 @@ func (p *PersistCookieJar) SetCookies(u *url.URL, cookies []*http.Cookie) {
|
||||
delete(globalCookies, cookie.Name)
|
||||
}
|
||||
|
||||
// 查找是否存在相同 name, path 和 domain 的 cookie
|
||||
existingCookies := p.hostMap[host][cookie.Name]
|
||||
found := false
|
||||
for i, existing := range existingCookies {
|
||||
if existing.Path == cookie.Path && existing.Domain == cookie.Domain {
|
||||
// 找到完全匹配的 cookie,替换它
|
||||
existingCookies[i] = cookie
|
||||
found = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if !found {
|
||||
// 没有找到匹配的,添加新的 cookie
|
||||
p.hostMap[host][cookie.Name] = append(p.hostMap[host][cookie.Name], cookie)
|
||||
}
|
||||
// 同一 host 下同名 cookie 直接覆盖,避免多个同名 cookie 导致旧值被选中
|
||||
p.hostMap[host][cookie.Name] = []*http.Cookie{cookie}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@ import (
|
||||
"likedream-goframe/internal/utils"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strings"
|
||||
|
||||
"github.com/bytedance/sonic"
|
||||
"github.com/samber/oops"
|
||||
@@ -284,25 +285,88 @@ func (s *SmsLoginHandler) GetCookieString() string {
|
||||
|
||||
// RefreshByTgc 使用保存的完整 cookie(包含 CASTGC 等长期凭证)重新去学校换取 CAS cookie。
|
||||
// tgc 参数是 SetLoginCookie 之后序列化的完整 cookie jar,包含 CASTGC(有效期10年)、
|
||||
// sessionToken 等认证信息,可以直接用来重新激活 session。
|
||||
// sessionToken 等认证信息。流程:先用 sessionToken 调用 getImUserToken 换取新的 CAS cookie,
|
||||
// 再激活 session。
|
||||
func (s *SmsLoginHandler) RefreshByTgc(ctx context.Context, tgc string, schoolId string) (cookie string, newTgc string) {
|
||||
jar := cookiejar.NewPersistCookieJar()
|
||||
jar.Deserialize(tgc)
|
||||
// 合并所有 host 的 cookie 到 global,消除因多 host 存储导致的重复 cookie
|
||||
jar.RemoveCookieInfo()
|
||||
s.client = httpclient.NewCpdailyClient()
|
||||
s.client.SetCookieJar(jar)
|
||||
|
||||
detail := school.GetSchoolDetail(ctx, schoolId)
|
||||
|
||||
logger.Logger.Info("[TGC] RefreshByTgc 开始用CASTGC重新激活session",
|
||||
logger.Logger.Info("[TGC] RefreshByTgc 开始用TGC换取CAS cookie",
|
||||
zap.String("schoolId", schoolId),
|
||||
zap.String("wecloudUrl", detail.WecloudUrl),
|
||||
zap.Int("tgcLen", len(tgc)),
|
||||
)
|
||||
|
||||
// 用保存的 cookie(含 CASTGC)重新激活 session
|
||||
ActivateSession(ctx, detail.WecloudUrl, s.client)
|
||||
// 从 cookie jar 中提取 sessionToken,用于换取新的 CAS cookie
|
||||
schoolUrl, _ := url.Parse(detail.WecloudUrl)
|
||||
sessionToken := ""
|
||||
for _, c := range jar.Cookies(schoolUrl) {
|
||||
if c.Name == "sessionToken" {
|
||||
sessionToken = c.Value
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
logger.Logger.Info("[TGC] RefreshByTgc ActivateSession完成")
|
||||
if sessionToken != "" {
|
||||
// 换取新的 CAS cookie(与 SetLoginCookie 相同的流程)
|
||||
getCookieUrl := fmt.Sprintf("%s%s", detail.WecloudUrl, "/wec-im-group/group/imUserToken/getImUserToken")
|
||||
|
||||
ampCookieMap := map[string]any{
|
||||
"AMP2": []map[string]any{
|
||||
{"path": "/", "value": sessionToken, "domain": "", "name": "sessionToken"},
|
||||
},
|
||||
"AMP1": []map[string]any{
|
||||
{"path": "/", "value": sessionToken, "domain": "", "name": "sessionToken"},
|
||||
},
|
||||
}
|
||||
|
||||
ampTokenString, e := sonic.Marshal(ampCookieMap)
|
||||
utils.OkOrPanic(e, oops.WithContext(ctx).Wrap)
|
||||
|
||||
ampTokenEncrypted := cryptoutil.DesEncrypt(ampTokenString, cryptoutil.Normal)
|
||||
ampToken := base64.StdEncoding.EncodeToString(ampTokenEncrypted)
|
||||
|
||||
ctx = utils.NewCpdailySmsContextBuilder().
|
||||
WithDeviceID(s.deviceID).
|
||||
WithTenantID(detail.Id).
|
||||
WithSessionToken(sessionToken).
|
||||
Build(ctx)
|
||||
|
||||
// 使用不复制 Cookie 头的重定向策略,避免旧 Cookie 覆盖 jar 中更新的值
|
||||
s.client.SetRedirectPolicy(resty.RedirectPolicyFunc(func(req *http.Request, via []*http.Request) error {
|
||||
if len(via) >= 50 {
|
||||
return fmt.Errorf("resty: stopped after 50 redirects")
|
||||
}
|
||||
// 只复制非 Cookie 头,让 jar 自动管理 Cookie
|
||||
for key, val := range via[0].Header {
|
||||
if !strings.EqualFold(key, "Cookie") {
|
||||
req.Header[key] = val
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}))
|
||||
req := s.client.R().
|
||||
SetHeader("AmpCookies", ampToken).
|
||||
SetContext(ctx)
|
||||
|
||||
setSmsRequestHeaders(ctx, req)
|
||||
|
||||
resp, e := req.Get(getCookieUrl)
|
||||
utils.OkOrPanic(e, oops.WithContext(ctx).Wrap)
|
||||
|
||||
respJson := utils.ReadJson[cpdailySmsCommonResponse[any]](resp.Body)
|
||||
respJson.EnsureSuccess()
|
||||
|
||||
logger.Logger.Info("[TGC] RefreshByTgc 换取CAS cookie完成")
|
||||
} else {
|
||||
logger.Logger.Warn("[TGC] RefreshByTgc 未找到sessionToken,跳过换取CAS cookie步骤")
|
||||
}
|
||||
|
||||
newTgc = tgc // TGC 保持不变(CASTGC 有效期10年)
|
||||
cookie = s.GetCookieString()
|
||||
|
||||
Reference in New Issue
Block a user