fix: auto re-login on 401 when sms-server restarts
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -30,11 +30,12 @@ const (
|
|||||||
// - NewBearerClient: 管理端(使用已有的 Bearer Token)
|
// - NewBearerClient: 管理端(使用已有的 Bearer Token)
|
||||||
// - NewUserTokenClient: 发送端(X-SMS-Token + 请求签名,仅可调用发送接口)
|
// - NewUserTokenClient: 发送端(X-SMS-Token + 请求签名,仅可调用发送接口)
|
||||||
type Client struct {
|
type Client struct {
|
||||||
baseURL string
|
baseURL string
|
||||||
mode authMode
|
mode authMode
|
||||||
bearer string
|
bearer string
|
||||||
userToken string
|
serviceToken string
|
||||||
httpClient *http.Client
|
userToken string
|
||||||
|
httpClient *http.Client
|
||||||
}
|
}
|
||||||
|
|
||||||
// Option 用于在构造 Client 时传入可选配置。
|
// Option 用于在构造 Client 时传入可选配置。
|
||||||
@@ -65,6 +66,7 @@ func NewServiceClient(baseURL, serviceToken string, opts ...Option) (*Client, er
|
|||||||
o(c)
|
o(c)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
c.serviceToken = serviceToken
|
||||||
token, err := c.serviceTokenLogin(context.Background(), serviceToken)
|
token, err := c.serviceTokenLogin(context.Background(), serviceToken)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("service token login: %w", err)
|
return nil, fmt.Errorf("service token login: %w", err)
|
||||||
@@ -197,6 +199,10 @@ func structToMap(v interface{}) (map[string]interface{}, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func doRequest[T any](c *Client, ctx context.Context, method, path string, body interface{}, query url.Values) (T, error) {
|
func doRequest[T any](c *Client, ctx context.Context, method, path string, body interface{}, query url.Values) (T, error) {
|
||||||
|
return doRequestRetry[T](c, ctx, method, path, body, query, false)
|
||||||
|
}
|
||||||
|
|
||||||
|
func doRequestRetry[T any](c *Client, ctx context.Context, method, path string, body interface{}, query url.Values, retried bool) (T, error) {
|
||||||
var zero T
|
var zero T
|
||||||
|
|
||||||
var bodyReader io.Reader
|
var bodyReader io.Reader
|
||||||
@@ -252,6 +258,15 @@ func doRequest[T any](c *Client, ctx context.Context, method, path string, body
|
|||||||
return zero, fmt.Errorf("unmarshal response (status %d): %w\nbody: %s", resp.StatusCode, err, string(respBody))
|
return zero, fmt.Errorf("unmarshal response (status %d): %w\nbody: %s", resp.StatusCode, err, string(respBody))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if apiResp.Code == 401 && c.serviceToken != "" && !retried {
|
||||||
|
newToken, loginErr := c.serviceTokenLogin(ctx, c.serviceToken)
|
||||||
|
if loginErr != nil {
|
||||||
|
return zero, &APIError{Code: 401, Message: apiResp.Message}
|
||||||
|
}
|
||||||
|
c.bearer = newToken
|
||||||
|
return doRequestRetry[T](c, ctx, method, path, body, query, true)
|
||||||
|
}
|
||||||
|
|
||||||
if apiResp.Code != 200 {
|
if apiResp.Code != 200 {
|
||||||
return zero, &APIError{Code: apiResp.Code, Message: apiResp.Message}
|
return zero, &APIError{Code: apiResp.Code, Message: apiResp.Message}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user