コード例 #1
0
        //获取ClientId
        private string GetClientId(StepFlyUser user)
        {
            if (user == null || string.IsNullOrWhiteSpace(user !.UserClientInfo))
            {
                return(Guid.NewGuid().ToString().Replace("-", ""));
            }

            return(user !.UserClientInfo);
        }
コード例 #2
0
        private async Task TryRelogin(StepFlyUser user, CancellationToken cancellationToken)
        {
            var needRefresh = user.TokenExpireTime < DateTime.Now;

            if (!needRefresh)
            {
                return;
            }

            var httpClient = _httpClientFactory.CreateClient("noRedirect");

            var content = new StringContent(XiaoMiConfig.GetReLoginRequestBody(user.AdditionalInfo, HttpUtility.UrlEncode(user.DeviceId, Encoding.UTF8)), Encoding.UTF8, "application/x-www-form-urlencoded");

            //add important headers
            content.Headers.Add("hm-privacy-diagnostics", "false");
            content.Headers.Add("app_name", "com.xiaomi.hm.health");
            content.Headers.Add("hm-privacy-ceip", "true");
            content.Headers.Add("X-Request-Id", Guid.NewGuid().ToString());

            try
            {
                using var response = await httpClient.PostAsync(XiaoMiConfig.ReLoginUrl, content, cancellationToken);

                if (response.StatusCode != HttpStatusCode.OK)
                {
                    return;
                }

                var responseContent = await response.Content.ReadAsStringAsync();

                _logger.LogInformation($"ReloginResponse Content: {responseContent}");

                //得到当前登录成功的用户信息
                var successModel = JsonSerializer.Deserialize <XiaoMiReLoginSuccessModel>(responseContent, new JsonSerializerOptions()
                {
                    IgnoreNullValues = true
                });
                if (string.IsNullOrEmpty(successModel.token_info?.app_token))
                {
                    return;
                }

                //更新用户的Token信息
                user.SetToken(successModel.token_info.app_token, DateTime.Now.AddDays(invalidHours));
                user.SetAdditionalInfo(successModel.token_info.login_token);
            }
            catch
            {
                return;
            }
        }
コード例 #3
0
        /// <summary>
        /// 获取修改步数的模型,用于序列化提交
        /// </summary>
        private LeXinUpdateStepModel GetUpdateStepModel(int step, StepFlyUser user)
        {
            LeXinUpdateStepModel model = new LeXinUpdateStepModel();

            LeXinStepItem item = new LeXinStepItem();

            item.SetStep(step);
            item.SetUserId(user.UserSystemId);
            item.SetDeviceId(user.DeviceId);

            model.List = new List <LeXinStepItem>()
            {
                item
            };
            return(model);
        }
コード例 #4
0
        public async Task <OperateResult> LoginToSystem <T>(T loginIno, CancellationToken cancellationToken = default)
        {
            var loginModel = loginIno as XiaoMiLoginModel;

            if (loginModel == null)
            {
                return(OperateResult.Failed(null, string.Empty, "当前登录信息转换失败"));
            }

            var existUser = await _userRepo.FindByUserKeyInfoAsync(loginModel.UserPhone, StepFlyProviderType.XiaoMi);

            OperateResult operateResult = await Login(loginModel, existUser, cancellationToken);

            if (!operateResult.Succeeded)
            {
                return(operateResult);
            }

            var result = operateResult.Information.PlayLoad !as XiaoMiLoginAPISuccessModel
                         ?? throw new SoftlyMiCakeException($"转换{nameof(XiaoMiLoginAPISuccessModel)}返回结果出错");

            //保存当前用户的信息
            if (!result.AlreadyHasUser)
            {
                var user = StepFlyUser.Create(loginModel.UserPhone, loginModel.Password, result.UserId);
                user.SetProvider(StepFlyProviderType.XiaoMi);
                user.SetToken(result.Token, DateTime.Now.AddDays(invalidHours));
                user.SetClientInfo(null, result.DeviceId);
                user.SetAdditionalInfo(result.LoginToken);

                await _userRepo.AddAsync(user);

                result.User = user;
            }
            else
            {
                existUser.SetToken(result.Token, DateTime.Now.AddDays(invalidHours));
                existUser.SetAdditionalInfo(result.LoginToken);
                existUser.SetPassword(loginModel.Password);
                //保证设备ID不为空
                existUser.SetClientInfo(existUser.UserClientInfo, existUser.DeviceId);
                result.User = existUser;
            }

            return(OperateResult.Success(HttpStatusCode.OK.ToString(), "登录成功", result));
        }
コード例 #5
0
        private async Task <OperateResult> Login(XiaoMiLoginModel loginInfo, StepFlyUser user, CancellationToken cancellationToken)
        {
            try
            {
                CheckValue.NotNullOrWhiteSpace(loginInfo.UserPhone, nameof(loginInfo.UserPhone));
                CheckValue.NotNullOrWhiteSpace(loginInfo.Password, nameof(loginInfo.Password));

                var httpClient = _httpClientFactory.CreateClient("noRedirect");

                //Step one : Get AccessToken
                var accessUrl = XiaoMiConfig.GetAccessUrl(loginInfo.UserPhone);

                var content = new StringContent(XiaoMiConfig.GetAccessRequestBody(loginInfo.UserPhone, loginInfo.Password), Encoding.UTF8, "application/x-www-form-urlencoded");
                //add important headers
                content.Headers.Add("hm-privacy-diagnostics", "false");
                content.Headers.Add("app_name", "com.xiaomi.hm.health");
                content.Headers.Add("hm-privacy-ceip", "true");
                content.Headers.Add("X-Request-Id", Guid.NewGuid().ToString());

                using var response = await httpClient.PostAsync(accessUrl, content, cancellationToken);

                if (response.StatusCode != HttpStatusCode.RedirectMethod)
                {
                    return(OperateResult.Failed(null, response.StatusCode.ToString(), "登录失败", "尝试获取AccessToken时失败"));
                }

                var parms = HttpUtility.ParseQueryString(response.Headers.Location.Query);

                var accessToken = parms["access"];

                if (string.IsNullOrWhiteSpace(accessToken))
                {
                    return(OperateResult.Failed(null, response.StatusCode.ToString(), "登录失败", "尝试获取AccessToken时失败"));
                }

                //Step two : Login to system
                string deviceId     = user?.DeviceId ?? IdentityHelper.GetRandomDeviceId();
                var    loginContent = new StringContent(XiaoMiConfig.GetLoginRequestBody(accessToken, HttpUtility.UrlEncode(deviceId, Encoding.UTF8)), Encoding.UTF8, "application/x-www-form-urlencoded");

                using var loginResponse = await httpClient.PostAsync(XiaoMiConfig.LoginUrl, loginContent, cancellationToken);

                loginResponse.EnsureSuccessStatusCode();

                var responseContent = await loginResponse.Content.ReadAsStringAsync();

                _logger.LogInformation(await loginContent.ReadAsStringAsync());
                _logger.LogInformation(responseContent);

                if (loginResponse.StatusCode != HttpStatusCode.OK)
                {
                    return(OperateResult.Failed(null, response.StatusCode.ToString(), "登录失败", responseContent));
                }

                //得到当前登录成功的用户信息
                var successModel = JsonSerializer.Deserialize <XiaoMiLoginSuccessModel>(responseContent, new JsonSerializerOptions()
                {
                    IgnoreNullValues = true
                });

                XiaoMiLoginAPISuccessModel result = new XiaoMiLoginAPISuccessModel()
                {
                    AlreadyHasUser  = user != null,
                    APIResponseData = responseContent,
                    DeviceId        = deviceId,
                    LoginToken      = successModel.token_info.login_token,
                    Token           = successModel.token_info.app_token,
                    UserId          = successModel.token_info.user_id,
                };

                return(OperateResult.Success(HttpStatusCode.OK.ToString(), "登录成功", result));
            }
            catch (Exception ex)
            {
                return(OperateResult.Failed(ex, "尝试登录时发生错误", ex.Message));
            }
        }
コード例 #6
0
        // 通过验证码登录
        private async Task <OperateResult> LoginWithAuthCode(LeXinAuthCodeLoginModel loginInfo, StepFlyUser existUser, CancellationToken cancellationToken = default)
        {
            try
            {
                CheckValue.NotNullOrWhiteSpace(loginInfo.LoginName, nameof(loginInfo.LoginName));
                CheckValue.NotNullOrWhiteSpace(loginInfo.AuthCode, nameof(loginInfo.AuthCode));

                var httpClient = _httpClientFactory.CreateClient();

                var clientId = GetClientId(existUser);
                var url      = GetAuthCodeLoginUrl(clientId);
                loginInfo.SetClientId(clientId);

                var jsonOptions = new JsonSerializerOptions()
                {
                    PropertyNamingPolicy = JsonNamingPolicy.CamelCase
                };
                var content = new StringContent(JsonSerializer.Serialize(loginInfo, jsonOptions), Encoding.UTF8, "application/json");

                using var response = await httpClient.PostAsync(url, content, cancellationToken);

                response.EnsureSuccessStatusCode();

                var responseContent = await response.Content.ReadAsStringAsync();

                _logger.LogInformation(await content.ReadAsStringAsync());
                _logger.LogInformation(responseContent);

                if (response.StatusCode != HttpStatusCode.OK)
                {
                    return(OperateResult.Failed(null, response.StatusCode.ToString(), "登录失败", responseContent));
                }

                if (!response.Headers.TryGetValues("Set-Cookie", out var cookies))
                {
                    var apiResult = JsonSerializer.Deserialize <LeXinHttpResponse>(responseContent, new JsonSerializerOptions()
                    {
                        PropertyNameCaseInsensitive = true
                    });
                    if (apiResult.Code != 200)
                    {
                        return(OperateResult.Failed(null, apiResult.Code.ToString(), apiResult.Msg));
                    }

                    _logger.LogInformation($"登录返回成功,但是并没有获取到Cookie & Code:{response.StatusCode} & ResponseContent:{responseContent}");
                    return(OperateResult.Failed(null, response.StatusCode.ToString(), "登录返回成功,但是并没有获取到Cookie", responseContent));
                }

                var currentCookie = string.Join("", cookies.Select(s => s.Split(";")[0]).ToArray());
                //得到当前登录成功的用户信息
                using var jsonDoc = JsonDocument.Parse(responseContent);
                var element = jsonDoc.RootElement.GetProperty("data");

                LeXinLoginAPISuccessModel result = new LeXinLoginAPISuccessModel()
                {
                    AlreadyHasUser  = existUser != null,
                    APIResponseData = element.GetRawText(),
                    ClientInfo      = clientId,
                    Cookie          = currentCookie
                };

                return(OperateResult.Success(HttpStatusCode.OK.ToString(), "登录成功", result));
            }
            catch (Exception ex)
            {
                return(OperateResult.Failed(ex, "尝试登录时发生错误", ex.Message));
            }
        }
コード例 #7
0
        public async Task <OperateResult> LoginToSystem <T>(T loginIno, CancellationToken cancellationToken = default)
        {
            var loginModel = loginIno as LeXinLoginModel;

            if (loginModel == null)
            {
                return(OperateResult.Failed(null, string.Empty, "当前登录信息转换失败"));
            }

            var existUser = await _userRepo.FindByUserKeyInfoAsync(loginModel.UserKeyInfo);

            OperateResult operateResult = null;

            if (loginModel.Type == LeXinLoginType.AuthCode)
            {
                operateResult = await LoginWithAuthCode(loginModel.AuthCodeLoginInfo, existUser, cancellationToken);
            }
            else if (loginModel.Type == LeXinLoginType.Password)
            {
                operateResult = await LoginWithPassword(loginModel.PasswordLoginInfo, existUser, cancellationToken);
            }

            if (operateResult != null)
            {
                if (!operateResult.Succeeded)
                {
                    return(operateResult);
                }

                var result = operateResult.Information.PlayLoad !as LeXinLoginAPISuccessModel
                             ?? throw new SoftlyMiCakeException($"转换{nameof(LeXinLoginAPISuccessModel)}返回结果出错");

                var userLoginInfo = JsonSerializer.Deserialize <LeXinUserLoginSuccessModel>(result.APIResponseData, new JsonSerializerOptions()
                {
                    PropertyNameCaseInsensitive = true
                });
                //保存当前用户的信息
                if (!result.AlreadyHasUser)
                {
                    var user = StepFlyUser.Create(loginModel.UserKeyInfo, loginModel.PasswordLoginInfo?.Password ?? "", userLoginInfo.UserId);
                    user.SetToken(result.Cookie, DateTimeHelper.ConvertStampToDateTime(userLoginInfo.ExpireAt, TimeStampType.ThirteenLength));
                    user.SetClientInfo(result.ClientInfo, null);

                    await _userRepo.AddAsync(user);

                    result.User = user;
                }
                else
                {
                    existUser.SetToken(result.Cookie, DateTimeHelper.ConvertStampToDateTime(userLoginInfo.ExpireAt, TimeStampType.ThirteenLength));
                    existUser.SetPassword(loginModel.PasswordLoginInfo?.Password);
                    //保证设备ID不为空
                    existUser.SetClientInfo(existUser.UserClientInfo, existUser.DeviceId);
                    result.User = existUser;
                }


                return(OperateResult.Success(HttpStatusCode.OK.ToString(), "登录成功", result));
            }
            else
            {
                return(OperateResult.Failed(null, "E0", "未找到对应的登录方式"));
            }
        }