fix: keep failed login authentication unchanged
This commit is contained in:
@@ -150,26 +150,29 @@ func (client *Client) loadAuthData() error {
|
||||
}
|
||||
|
||||
func (client *Client) ensureIdentity() {
|
||||
client.updateAuthData(func(authData *AuthData) {
|
||||
if authData.PassO == "" {
|
||||
authData.PassO = randomString(16, "0123456789abcdef")
|
||||
}
|
||||
if authData.DeviceID == "" {
|
||||
authData.DeviceID = randomString(16, "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_-")
|
||||
}
|
||||
if authData.UA != "" {
|
||||
return
|
||||
}
|
||||
countryCode := "CN"
|
||||
if parts := strings.Split(client.locale, "_"); len(parts) == 2 {
|
||||
countryCode = parts[1]
|
||||
}
|
||||
id1 := randomString(40, "0123456789ABCDEF")
|
||||
id2 := randomString(32, "0123456789ABCDEF")
|
||||
id3 := randomString(32, "0123456789ABCDEF")
|
||||
id4 := randomString(40, "0123456789ABCDEF")
|
||||
authData.UA = fmt.Sprintf("Android-15-11.0.701-Xiaomi-23046RP50C-OS2.0.212.0.VMYCNXM-%s-%s-%s-%s-SmartHome-MI_APP_STORE-%s|%s|%s-64", id1, countryCode, id3, id2, id1, id4, authData.PassO)
|
||||
})
|
||||
client.setAuthData(client.authDataWithIdentity(client.AuthData()))
|
||||
}
|
||||
|
||||
func (client *Client) authDataWithIdentity(authData AuthData) AuthData {
|
||||
if authData.PassO == "" {
|
||||
authData.PassO = randomString(16, "0123456789abcdef")
|
||||
}
|
||||
if authData.DeviceID == "" {
|
||||
authData.DeviceID = randomString(16, "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_-")
|
||||
}
|
||||
if authData.UA != "" {
|
||||
return authData
|
||||
}
|
||||
countryCode := "CN"
|
||||
if parts := strings.Split(client.locale, "_"); len(parts) == 2 {
|
||||
countryCode = parts[1]
|
||||
}
|
||||
id1 := randomString(40, "0123456789ABCDEF")
|
||||
id2 := randomString(32, "0123456789ABCDEF")
|
||||
id3 := randomString(32, "0123456789ABCDEF")
|
||||
id4 := randomString(40, "0123456789ABCDEF")
|
||||
authData.UA = fmt.Sprintf("Android-15-11.0.701-Xiaomi-23046RP50C-OS2.0.212.0.VMYCNXM-%s-%s-%s-%s-SmartHome-MI_APP_STORE-%s|%s|%s-64", id1, countryCode, id3, id2, id1, id4, authData.PassO)
|
||||
return authData
|
||||
}
|
||||
|
||||
func randomString(length int, alphabet string) string {
|
||||
@@ -318,9 +321,9 @@ func (value *stringOrNumber) UnmarshalJSON(payload []byte) error {
|
||||
func (client *Client) Login(ctx context.Context) (AuthData, error) {
|
||||
client.loginMu.Lock()
|
||||
defer client.loginMu.Unlock()
|
||||
client.ensureIdentity()
|
||||
candidate := client.authDataWithIdentity(client.AuthData())
|
||||
|
||||
location, refreshedAuthData, err := client.getLocation(ctx)
|
||||
location, refreshedAuthData, err := client.getLocation(ctx, candidate)
|
||||
if err != nil {
|
||||
return AuthData{}, err
|
||||
}
|
||||
@@ -330,7 +333,7 @@ func (client *Client) Login(ctx context.Context) (AuthData, error) {
|
||||
}
|
||||
return client.AuthData(), nil
|
||||
}
|
||||
loginData, err := client.getQRLoginData(ctx, location)
|
||||
loginData, err := client.getQRLoginData(ctx, location, candidate)
|
||||
if err != nil {
|
||||
return AuthData{}, err
|
||||
}
|
||||
@@ -352,10 +355,10 @@ func (client *Client) Login(ctx context.Context) (AuthData, error) {
|
||||
}
|
||||
}
|
||||
}
|
||||
return client.completeQRLogin(ctx, loginData)
|
||||
return client.completeQRLogin(ctx, loginData, candidate)
|
||||
}
|
||||
|
||||
func (client *Client) getLocation(ctx context.Context) (url.Values, *AuthData, error) {
|
||||
func (client *Client) getLocation(ctx context.Context, authData AuthData) (url.Values, *AuthData, error) {
|
||||
httpClient := client.newSession()
|
||||
serviceURL, err := url.Parse(client.serviceLoginURL)
|
||||
if err != nil {
|
||||
@@ -370,7 +373,7 @@ func (client *Client) getLocation(ctx context.Context) (url.Values, *AuthData, e
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
client.setLoginHeaders(request, true)
|
||||
client.setLoginHeaders(request, authData, true)
|
||||
var data serviceLoginData
|
||||
if err := client.doLoginRequestWithClient(httpClient, request, false, &data); err != nil {
|
||||
return nil, nil, err
|
||||
@@ -383,7 +386,7 @@ func (client *Client) getLocation(ctx context.Context) (url.Values, *AuthData, e
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
client.setLoginHeaders(refreshRequest, false)
|
||||
client.setLoginHeaders(refreshRequest, authData, false)
|
||||
response, err := httpClient.Do(refreshRequest)
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("refresh login token: %w", err)
|
||||
@@ -399,7 +402,7 @@ func (client *Client) getLocation(ctx context.Context) (url.Values, *AuthData, e
|
||||
if string(body) != "ok" {
|
||||
return nil, nil, &LoginError{Code: -1, Message: string(body)}
|
||||
}
|
||||
candidate := client.AuthData()
|
||||
candidate := authData
|
||||
serviceTokenReceived := updateAuthDataFromCookies(&candidate, httpClient, response.Request.URL)
|
||||
candidate.Ssecurity = data.Ssecurity
|
||||
if !serviceTokenReceived || !candidate.complete() {
|
||||
@@ -415,7 +418,7 @@ func (client *Client) getLocation(ctx context.Context) (url.Values, *AuthData, e
|
||||
return locationURL.Query(), nil, nil
|
||||
}
|
||||
|
||||
func (client *Client) getQRLoginData(ctx context.Context, location url.Values) (qrLoginData, error) {
|
||||
func (client *Client) getQRLoginData(ctx context.Context, location url.Values, authData AuthData) (qrLoginData, error) {
|
||||
location.Set("theme", "")
|
||||
location.Set("bizDeviceType", "")
|
||||
location.Set("_hasLogo", "false")
|
||||
@@ -430,7 +433,7 @@ func (client *Client) getQRLoginData(ctx context.Context, location url.Values) (
|
||||
if err != nil {
|
||||
return qrLoginData{}, err
|
||||
}
|
||||
client.setLoginHeaders(request, false)
|
||||
client.setLoginHeaders(request, authData, false)
|
||||
var data qrLoginData
|
||||
if err := client.doLoginRequest(request, true, &data); err != nil {
|
||||
return qrLoginData{}, err
|
||||
@@ -441,7 +444,7 @@ func (client *Client) getQRLoginData(ctx context.Context, location url.Values) (
|
||||
return data, nil
|
||||
}
|
||||
|
||||
func (client *Client) completeQRLogin(ctx context.Context, loginData qrLoginData) (AuthData, error) {
|
||||
func (client *Client) completeQRLogin(ctx context.Context, loginData qrLoginData, authData AuthData) (AuthData, error) {
|
||||
pollContext, cancel := context.WithTimeout(ctx, qrLoginTimeout)
|
||||
defer cancel()
|
||||
httpClient := client.newSession()
|
||||
@@ -449,7 +452,7 @@ func (client *Client) completeQRLogin(ctx context.Context, loginData qrLoginData
|
||||
if err != nil {
|
||||
return AuthData{}, err
|
||||
}
|
||||
client.setLoginHeaders(request, false)
|
||||
client.setLoginHeaders(request, authData, false)
|
||||
var data longPollData
|
||||
if err := client.doLoginRequestWithClient(httpClient, request, true, &data); err != nil {
|
||||
if errors.Is(err, context.DeadlineExceeded) {
|
||||
@@ -461,7 +464,7 @@ func (client *Client) completeQRLogin(ctx context.Context, loginData qrLoginData
|
||||
if err != nil {
|
||||
return AuthData{}, err
|
||||
}
|
||||
client.setLoginHeaders(callback, false)
|
||||
client.setLoginHeaders(callback, authData, false)
|
||||
response, err := httpClient.Do(callback)
|
||||
if err != nil {
|
||||
return AuthData{}, fmt.Errorf("complete login callback: %w", err)
|
||||
@@ -474,7 +477,7 @@ func (client *Client) completeQRLogin(ctx context.Context, loginData qrLoginData
|
||||
if response.StatusCode < 200 || response.StatusCode >= 300 {
|
||||
return AuthData{}, &LoginError{Code: response.StatusCode, Message: "登录回调失败"}
|
||||
}
|
||||
candidate := client.AuthData()
|
||||
candidate := authData
|
||||
candidate.Ssecurity = ""
|
||||
candidate.UserID = ""
|
||||
candidate.CUserID = ""
|
||||
@@ -530,8 +533,7 @@ func (client *Client) doLoginRequestWithClient(httpClient *http.Client, request
|
||||
return nil
|
||||
}
|
||||
|
||||
func (client *Client) setLoginHeaders(request *http.Request, withCookies bool) {
|
||||
authData := client.AuthData()
|
||||
func (client *Client) setLoginHeaders(request *http.Request, authData AuthData, withCookies bool) {
|
||||
request.Header.Set("User-Agent", authData.UA)
|
||||
request.Header.Set("Connection", "keep-alive")
|
||||
request.Header.Set("Accept-Encoding", "gzip")
|
||||
@@ -583,7 +585,7 @@ func (client *Client) refreshToken(ctx context.Context) error {
|
||||
if available {
|
||||
return nil
|
||||
}
|
||||
_, refreshedAuthData, err := client.getLocation(ctx)
|
||||
_, refreshedAuthData, err := client.getLocation(ctx, client.AuthData())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user