Spaces:
Paused
Paused
add session cookies to upstream requests
Browse files- internal/auth/anonymous.go +78 -7
- internal/upstream/client.go +8 -0
internal/auth/anonymous.go
CHANGED
|
@@ -4,6 +4,8 @@ import (
|
|
| 4 |
"encoding/json"
|
| 5 |
"fmt"
|
| 6 |
"net/http"
|
|
|
|
|
|
|
| 7 |
|
| 8 |
"zai-proxy/internal/proxy"
|
| 9 |
)
|
|
@@ -12,22 +14,91 @@ type AnonymousAuthResponse struct {
|
|
| 12 |
Token string `json:"token"`
|
| 13 |
}
|
| 14 |
|
| 15 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 16 |
func GetAnonymousToken() (string, error) {
|
| 17 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 18 |
if err != nil {
|
| 19 |
return "", err
|
| 20 |
}
|
| 21 |
-
defer
|
| 22 |
|
| 23 |
-
if
|
| 24 |
-
return "", fmt.Errorf("status %d",
|
| 25 |
}
|
| 26 |
|
| 27 |
var authResp AnonymousAuthResponse
|
| 28 |
-
if err := json.NewDecoder(
|
| 29 |
return "", err
|
| 30 |
}
|
| 31 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 32 |
return authResp.Token, nil
|
| 33 |
-
}
|
|
|
|
| 4 |
"encoding/json"
|
| 5 |
"fmt"
|
| 6 |
"net/http"
|
| 7 |
+
"net/http/cookiejar"
|
| 8 |
+
"sync"
|
| 9 |
|
| 10 |
"zai-proxy/internal/proxy"
|
| 11 |
)
|
|
|
|
| 14 |
Token string `json:"token"`
|
| 15 |
}
|
| 16 |
|
| 17 |
+
type SessionData struct {
|
| 18 |
+
Token string
|
| 19 |
+
Cookies []*http.Cookie
|
| 20 |
+
}
|
| 21 |
+
|
| 22 |
+
var (
|
| 23 |
+
sessionMu sync.RWMutex
|
| 24 |
+
session *SessionData
|
| 25 |
+
)
|
| 26 |
+
|
| 27 |
func GetAnonymousToken() (string, error) {
|
| 28 |
+
sessionMu.RLock()
|
| 29 |
+
if session != nil {
|
| 30 |
+
t := session.Token
|
| 31 |
+
sessionMu.RUnlock()
|
| 32 |
+
return t, nil
|
| 33 |
+
}
|
| 34 |
+
sessionMu.RUnlock()
|
| 35 |
+
return RefreshAnonymousSession()
|
| 36 |
+
}
|
| 37 |
+
|
| 38 |
+
func GetAnonymousSession() (*SessionData, error) {
|
| 39 |
+
sessionMu.RLock()
|
| 40 |
+
if session != nil {
|
| 41 |
+
s := session
|
| 42 |
+
sessionMu.RUnlock()
|
| 43 |
+
return s, nil
|
| 44 |
+
}
|
| 45 |
+
sessionMu.RUnlock()
|
| 46 |
+
return nil, fmt.Errorf("no session")
|
| 47 |
+
}
|
| 48 |
+
|
| 49 |
+
func RefreshAnonymousSession() (string, error) {
|
| 50 |
+
jar, _ := cookiejar.New(nil)
|
| 51 |
+
client := proxy.GetHTTPClient()
|
| 52 |
+
|
| 53 |
+
// Primero visitar la página principal para obtener cookies CDN
|
| 54 |
+
req1, _ := http.NewRequest("GET", "https://chat.z.ai/", nil)
|
| 55 |
+
req1.Header.Set("User-Agent", "Mozilla/5.0 (X11; Linux x86_64; rv:150.0) Gecko/20100101 Firefox/150.0")
|
| 56 |
+
req1.Header.Set("Accept", "text/html")
|
| 57 |
+
resp1, err := client.Do(req1)
|
| 58 |
+
if err == nil {
|
| 59 |
+
resp1.Body.Close()
|
| 60 |
+
if resp1.Header["Set-Cookie"] != nil {
|
| 61 |
+
jar.SetCookies(req1.URL, resp1.Cookies())
|
| 62 |
+
}
|
| 63 |
+
}
|
| 64 |
+
|
| 65 |
+
// Luego obtener el token
|
| 66 |
+
req2, _ := http.NewRequest("GET", "https://chat.z.ai/api/v1/auths/", nil)
|
| 67 |
+
req2.Header.Set("User-Agent", "Mozilla/5.0 (X11; Linux x86_64; rv:150.0) Gecko/20100101 Firefox/150.0")
|
| 68 |
+
req2.Header.Set("Accept", "application/json")
|
| 69 |
+
req2.Header.Set("Origin", "https://chat.z.ai")
|
| 70 |
+
// Agregar cookies del jar
|
| 71 |
+
for _, c := range jar.Cookies(req2.URL) {
|
| 72 |
+
req2.AddCookie(c)
|
| 73 |
+
}
|
| 74 |
+
|
| 75 |
+
resp2, err := client.Do(req2)
|
| 76 |
if err != nil {
|
| 77 |
return "", err
|
| 78 |
}
|
| 79 |
+
defer resp2.Body.Close()
|
| 80 |
|
| 81 |
+
if resp2.StatusCode != http.StatusOK {
|
| 82 |
+
return "", fmt.Errorf("status %d", resp2.StatusCode)
|
| 83 |
}
|
| 84 |
|
| 85 |
var authResp AnonymousAuthResponse
|
| 86 |
+
if err := json.NewDecoder(resp2.Body).Decode(&authResp); err != nil {
|
| 87 |
return "", err
|
| 88 |
}
|
| 89 |
|
| 90 |
+
// Guardar cookies
|
| 91 |
+
allCookies := jar.Cookies(req2.URL)
|
| 92 |
+
allCookies = append(allCookies, resp2.Cookies()...)
|
| 93 |
+
// Agregar token como cookie
|
| 94 |
+
allCookies = append(allCookies, &http.Cookie{Name: "token", Value: authResp.Token})
|
| 95 |
+
|
| 96 |
+
sessionMu.Lock()
|
| 97 |
+
session = &SessionData{
|
| 98 |
+
Token: authResp.Token,
|
| 99 |
+
Cookies: allCookies,
|
| 100 |
+
}
|
| 101 |
+
sessionMu.Unlock()
|
| 102 |
+
|
| 103 |
return authResp.Token, nil
|
| 104 |
+
}
|
internal/upstream/client.go
CHANGED
|
@@ -264,3 +264,11 @@ body := map[string]interface{}{
|
|
| 264 |
|
| 265 |
return resp, targetModel, nil
|
| 266 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 264 |
|
| 265 |
return resp, targetModel, nil
|
| 266 |
}
|
| 267 |
+
|
| 268 |
+
if sess, err := auth.GetAnonymousSession(); err == nil {
|
| 269 |
+
var cookieStrs []string
|
| 270 |
+
for _, c := range sess.Cookies {
|
| 271 |
+
cookieStrs = append(cookieStrs, c.Name+"="+c.Value)
|
| 272 |
+
}
|
| 273 |
+
req.Header.Set("Cookie", strings.Join(cookieStrs, "; "))
|
| 274 |
+
}
|