leonardo: 把 cross-origin-cookie 401 判为会话被吊销
This commit is contained in:
@@ -207,6 +207,9 @@ func (c *Client) GetSession(ctx context.Context, cookie string) (*Session, error
|
|||||||
var setCookies []string
|
var setCookies []string
|
||||||
var err error
|
var err error
|
||||||
var warmed bool
|
var warmed bool
|
||||||
|
// 401 from cross-origin-cookie means Leonardo已经作废了这个 session(不是人机校验),
|
||||||
|
// 记下来好把日志写成"会话被吊销"而不是含糊的 get-session null。
|
||||||
|
warmStatus := 0
|
||||||
for attempt := 0; attempt < getSessionAttempts; attempt++ {
|
for attempt := 0; attempt < getSessionAttempts; attempt++ {
|
||||||
if attempt > 0 {
|
if attempt > 0 {
|
||||||
select {
|
select {
|
||||||
@@ -227,7 +230,9 @@ func (c *Client) GetSession(ctx context.Context, cookie string) (*Session, error
|
|||||||
// better-auth cookie cache (and CF_Access_Token). Without it get-session
|
// better-auth cookie cache (and CF_Access_Token). Without it get-session
|
||||||
// answers 200 null even for a perfectly healthy cookie.
|
// answers 200 null even for a perfectly healthy cookie.
|
||||||
warmed = false
|
warmed = false
|
||||||
if warmCookies, werr := c.warmSession(ctx, client, send); werr == nil {
|
warmCookies, wstatus, werr := c.warmSession(ctx, client, send)
|
||||||
|
warmStatus = wstatus
|
||||||
|
if werr == nil {
|
||||||
warmed = true
|
warmed = true
|
||||||
if merged := mergeCookies(send, warmCookies); merged != send && keepsSession(merged) {
|
if merged := mergeCookies(send, warmCookies); merged != send && keepsSession(merged) {
|
||||||
send = merged
|
send = merged
|
||||||
@@ -284,6 +289,10 @@ func (c *Client) GetSession(ctx context.Context, cookie string) (*Session, error
|
|||||||
return nil, fmt.Errorf("%w: get-session non-json", ErrTemporaryUpstream)
|
return nil, fmt.Errorf("%w: get-session non-json", ErrTemporaryUpstream)
|
||||||
}
|
}
|
||||||
if strings.TrimSpace(raw.Session.AccessToken) == "" {
|
if strings.TrimSpace(raw.Session.AccessToken) == "" {
|
||||||
|
if warmStatus == 401 {
|
||||||
|
// Leonardo 明确拒了这份 session_token:服务端已把会话吊销,重新导入 cookie 才能恢复。
|
||||||
|
return nil, fmt.Errorf("%w: session revoked (cross-origin-cookie 401)", ErrAuth)
|
||||||
|
}
|
||||||
if !warmed {
|
if !warmed {
|
||||||
// A cold get-session (the cookie cache was never refreshed) answers null
|
// A cold get-session (the cookie cache was never refreshed) answers null
|
||||||
// for healthy accounts too — temporary, never a reason to kill the account.
|
// for healthy accounts too — temporary, never a reason to kill the account.
|
||||||
@@ -321,23 +330,23 @@ func (c *Client) GetSession(ctx context.Context, cookie string) (*Session, error
|
|||||||
// warmSession calls cross-origin-cookie, whose response refreshes better-auth's
|
// warmSession calls cross-origin-cookie, whose response refreshes better-auth's
|
||||||
// cookie cache and CF_Access_Token. It returns the Set-Cookie headers; a
|
// cookie cache and CF_Access_Token. It returns the Set-Cookie headers; a
|
||||||
// checkpoint answer (403/429) is an error, since get-session would then be cold.
|
// checkpoint answer (403/429) is an error, since get-session would then be cold.
|
||||||
func (c *Client) warmSession(ctx context.Context, client tlsclient.HttpClient, cookie string) ([]string, error) {
|
func (c *Client) warmSession(ctx context.Context, client tlsclient.HttpClient, cookie string) ([]string, int, error) {
|
||||||
req, err := http.NewRequest(http.MethodGet, appBase+"/api/auth/cross-origin-cookie", nil)
|
req, err := http.NewRequest(http.MethodGet, appBase+"/api/auth/cross-origin-cookie", nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, 0, err
|
||||||
}
|
}
|
||||||
req = req.WithContext(ctx)
|
req = req.WithContext(ctx)
|
||||||
req.Header = sessionHeader(cookie)
|
req.Header = sessionHeader(cookie)
|
||||||
resp, err := client.Do(req)
|
resp, err := client.Do(req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, 0, err
|
||||||
}
|
}
|
||||||
defer resp.Body.Close()
|
defer resp.Body.Close()
|
||||||
_, _ = io.Copy(io.Discard, resp.Body)
|
_, _ = io.Copy(io.Discard, resp.Body)
|
||||||
if resp.StatusCode == 403 || resp.StatusCode == 429 {
|
if resp.StatusCode == 403 || resp.StatusCode == 429 {
|
||||||
return nil, fmt.Errorf("cross-origin-cookie http %d", resp.StatusCode)
|
return nil, resp.StatusCode, fmt.Errorf("cross-origin-cookie http %d", resp.StatusCode)
|
||||||
}
|
}
|
||||||
return resp.Header["Set-Cookie"], nil
|
return resp.Header["Set-Cookie"], resp.StatusCode, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// fetchSession performs one get-session call and returns its status, body and
|
// fetchSession performs one get-session call and returns its status, body and
|
||||||
|
|||||||
Reference in New Issue
Block a user