//获取ClientId private string GetClientId(StepFlyUser user) { if (user == null || string.IsNullOrWhiteSpace(user !.UserClientInfo)) { return(Guid.NewGuid().ToString().Replace("-", "")); } return(user !.UserClientInfo); }
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; } }
/// <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); }
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)); }
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)); } }
// 通过验证码登录 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)); } }
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", "未找到对应的登录方式")); } }