/// <summary> /// Initialize authentication. /// https://github.com/cyberjunky/python-garminconnect/blob/master/garminconnect/__init__.py#L16 /// </summary> public async Task InitAuth() { object queryParams = new { clientId = "GarminConnect", consumeServiceTicket = "false", createAccountShown = "true", cssUrl = "https://static.garmincdn.com/com.garmin.connect/ui/css/gauth-custom-v1.2-min.css", displayNameShown = "false", embedWidget = "false", gauthHost = "https://sso.garmin.com/sso", generateExtraServiceTicket = "false", id = "gauth-widget", initialFocus = "true", locale = "en_US", openCreateAccount = "false", redirectAfterAccountCreationUrl = "https://connect.garmin.com/", redirectAfterAccountLoginUrl = "https://connect.garmin.com/", rememberMeChecked = "false", rememberMeShown = "true", service = "https://connect.garmin.com", source = "https://connect.garmin.com", usernameShow = "false", webhost = "https://connect.garmin.com" }; string loginForm = null; try { loginForm = await SIGNIN_URL .WithHeader("User-Agent", USERAGENT) .WithHeader("origin", ORIGIN) .SetQueryParams(queryParams) .WithCookies(out _jar) .GetStringAsync(); } catch (FlurlHttpException e) { Log.Error(e, "No login form."); throw; } object loginData = new { embed = "true", username = _config.Garmin.Email, password = _config.Garmin.Password, lt = "e1s1", _eventId = "submit", displayNameRequired = "false", }; string authResponse = null; try { authResponse = await SIGNIN_URL .WithHeader("User-Agent", USERAGENT) .WithHeader("origin", ORIGIN) .SetQueryParams(queryParams) .WithCookies(_jar) .PostUrlEncodedAsync(loginData) .ReceiveString(); } catch (FlurlHttpException e) { Log.Error(e, "Authentication Failed."); throw; } // Check we have SSO guid in the cookies if (!_jar.Any(c => c.Name == "GARMIN-SSO-GUID")) { Log.Error("Missing Garmin auth cookie."); throw new Exception("Failed to find Garmin auth cookie."); } //Try to find the full post login url in response var regex2 = new Regex("var response_url(\\s+) = (\\\"|\\').*?ticket=(?<ticket>[\\w\\-]+)(\\\"|\\')"); var match = regex2.Match(authResponse); if (!match.Success) { Log.Error("Missing service ticket."); throw new Exception("Failed to find service ticket."); } var ticket = match.Groups.GetValueOrDefault("ticket").Value; if (string.IsNullOrEmpty(ticket)) { Log.Error("Failed to parse service ticket."); throw new Exception("Failed to parse service ticket."); } queryParams = new { ticket = ticket }; // Second Auth Step // Needs a service ticket from the previous step try { var authResponse2 = await BASE_URL .WithCookies(_jar) .SetQueryParams(queryParams) .GetStringAsync(); } catch (FlurlHttpException e) { Log.Error(e, "Second auth step failed."); throw; } // Check login try { var response = await PROFILE_URL .WithHeader("User-Agent", USERAGENT) .WithHeader("origin", ORIGIN) .WithCookies(_jar) .GetJsonAsync(); } catch (FlurlHttpException e) { Log.Error(e, "Login check failed."); throw; } }