I’m kinda stuck. I have been trying to build a program to:
- Open Google Chrome using Selenium
- Developer tools tab open also
- Intercept all request on the network tab
- Write those requests to the disk, to temporary files with the prefix of REQUEST or RESPONSE
- Intercept the Bearer token from the request
- Use this Bearer Token and other headers on HttpClient
For now, i am not working on steps 5 and 6. I’ve been manually copying the Bearer Token from the developer tools and trying to make the POST Request. However, i’m always receiving the message “JWT Sequence Invalid”.
The bearer token from the login is different from the one when i attempt to search for some data. I’ve noticed it also, and i’m using the correct JWT Token.
Am i hitting a CFSR wall in here? Because i’m attempting to do the exact same thing, same data, and still not successfull.
I’ve tried to do the same thing with httpclient straightforward (without intercepting google chrome), but i do hit a wall that i don’t receive an password on the response headers and i’m unable to continue from there.
Any input is appreciated. To any1 who can give it a look and help:
- There’s this method called LoginAsync. It will login on the site and search for the proper data
- https://esbapi.santander.com.br/people/v3/person-code/by-document-number?gw-app-key=bfa4d8e04f460137b98e005056a171c8 – this is the URL for the POST request. To this URL you send the json payload and the bearer token.
- The post request is the one just after the OPTIONS request on httpclient.
Sorry for the messy code, trying to get it to work before making things better.
Thanks in advance for your attention.
using System.Text;
using Newtonsoft.Json;
using System.Net.Http.Headers;
using System.Net;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Support.UI;
using SeleniumExtras.WaitHelpers;
using OpenQA.Selenium.DevTools;
using System.Text.RegularExpressions;
namespace LoginAutomation;
class Program
{
private static string documentsPath = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
static async Task Main(string[] args)
{
await DeleteFiles();
var counter = new Counter();
var logs = new List<(string FileName, string Content)>();
var chromeOptions = new ChromeOptions();
chromeOptions.AddArgument("--auto-open-devtools-for-tabs");
using (var driver = new ChromeDriver(chromeOptions))
{
var patterns = new Dictionary<string, Regex>
{
{ "x-access-token", new Regex(@"""x-access-token""s*:s*""([^""]+)""", RegexOptions.Compiled) },
{ "x-access-token-expiry", new Regex(@"""x-access-token-expiry""s*:s*""([^""]+)""", RegexOptions.Compiled) },
{ "x-access-token-jwt", new Regex(@"""x-access-token-jwt""s*:s*""([^""]+)""", RegexOptions.Compiled) },
{ "x-access-token-sequence", new Regex(@"""x-access-token-sequence""s*:s*""([^""]+)""", RegexOptions.Compiled) },
{ "x-access-token-type", new Regex(@"""x-access-token-type""s*:s*""([^""]+)""", RegexOptions.Compiled) },
{ "x-apigee-access-token", new Regex(@"""x-apigee-access-token""s*:s*""([^""]+)""", RegexOptions.Compiled) },
{ "password", new Regex(@"""password""s*:s*""([^""]+)""", RegexOptions.Compiled) }
};
IDevTools devTools = driver;
DevToolsSession session = devTools.GetDevToolsSession();
await session.Domains.Network.EnableNetwork();
session.DevToolsEventReceived += async (sender, e) =>
{
await HandleDevToolsEvent(sender, e, documentsPath, counter, logs);
};
driver.Navigate().GoToUrl("https://www.santandernegocios.com.br/portaldenegocios/#/externo");
await LoginAsync(driver, "EX108593", "@BARC02", "14810823000197");
await Task.Delay(15000);
foreach (var log in logs)
{
await System.IO.File.WriteAllTextAsync(log.FileName, log.Content);
Console.WriteLine($"Written to file: {log.FileName}");
}
var passwordPattern = new Regex(@"""s*passwords*""s*:s*""([^""]+)""", RegexOptions.Compiled);
var seleniumCookies = driver.Manage().Cookies.AllCookies;
var cookies = new CookieContainer();
foreach (var seleniumCookie in seleniumCookies)
{
cookies.Add(new System.Net.Cookie(seleniumCookie.Name, seleniumCookie.Value, seleniumCookie.Path, seleniumCookie.Domain)
{
Secure = seleniumCookie.Secure,
HttpOnly = seleniumCookie.IsHttpOnly,
Expires = seleniumCookie.Expiry ?? DateTime.MinValue
});
}
var handler = new HttpClientHandler { CookieContainer = cookies };
var result = ReadFilesWithPrefix(documentsPath, new[] { "REQUEST", "RESPONSE" });
var results = result
.SelectMany(kvp => patterns.Select(pattern => new
{
FileName = kvp.Key,
Type = pattern.Key,
Value = kvp.Value
.SelectMany(line => pattern.Value.Matches(line))
.Where(match => match.Success)
.Select(match => match.Groups[1].Value)
.FirstOrDefault()
}))
.Where(x => x.Value != null)
.Select(x => new KeyValuePair<string, string>(x.Type, x.Value))
.ToList();
await DeleteFiles();
using (var client = new HttpClient(handler))
{
client.DefaultRequestHeaders.Add("origin", "https://www.santandernegocios.com.br");
client.DefaultRequestHeaders.Add("access-control-request-method", "POST");
HttpRequestMessage optionsRequest = new HttpRequestMessage(HttpMethod.Options, "https://esbapi.santander.com.br/people/v3/person-code/by-document-number?gw-app-key=bfa4d8e04f460137b98e005056a171c8");
var response = await client.SendAsync(optionsRequest);
var content = await response.Content.ReadAsStringAsync();
if (response.IsSuccessStatusCode)//options to search for CNPJ
{
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("text/plain"));
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("*/*"));
client.DefaultRequestHeaders.AcceptEncoding.Clear();
client.DefaultRequestHeaders.AcceptEncoding.Add(new StringWithQualityHeaderValue("gzip"));
client.DefaultRequestHeaders.AcceptEncoding.Add(new StringWithQualityHeaderValue("deflate"));
client.DefaultRequestHeaders.AcceptEncoding.Add(new StringWithQualityHeaderValue("br"));
client.DefaultRequestHeaders.AcceptEncoding.Add(new StringWithQualityHeaderValue("zstd"));
client.DefaultRequestHeaders.AcceptLanguage.Clear();
client.DefaultRequestHeaders.AcceptLanguage.Add(new StringWithQualityHeaderValue("en-US"));
client.DefaultRequestHeaders.AcceptLanguage.Add(new StringWithQualityHeaderValue("en", 0.9));
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", "OWUxOWVkOTAtNTY0Yi0xMWVmLTlkODYtZDcxYjJkNjVjZWEwOmV5SjBlWEFpT2lKS1YxUWlMQ0poYkdjaU9pSklVekkxTmlKOS5leUp6ZFdJaU9pSTVaVEU1WldRNU1DMDFOalJpTFRFeFpXWXRPV1E0Tmkxa056RmlNbVEyTldObFlUQWlMQ0poZFdRaU9pSmlabUUwWkRobE1EUm1ORFl3TVRNM1lqazRaVEF3TlRBMU5tRXhOekZqT0NJc0ltTnNhV1Z1ZEVsa0lqb2lZbVpoTkdRNFpUQTBaalEyTURFek4ySTVPR1V3TURVd05UWmhNVGN4WXpnaUxDSm1iR0ZuVFdsbmNtRmtieUk2ZEhKMVpTd2lhV0YwVFhNaU9qRTNNak15TURZNE1qVTJNakVzSW1semN5STZJbHAxY0M1dFpTQkhZWFJsZDJGNUlpd2ljMlZ6YzJsdmJrbGtJam9pT1dVeE9XVmtPVEF0TlRZMFlpMHhNV1ZtTFRsa09EWXRaRGN4WWpKa05qVmpaV0V3SWl3aWRIbHdaU0k2SWtKbFlYSmxjaUlzSW1WNGNDSTZNVGN5TXpJd056Y3lOU3dpYVdGMElqb3hOekl6TWpBMk9ESTFMQ0p6WlhFaU9qSXNJbXAwYVNJNklqbGxZVGsxWXpVd0xUVTJOR0l0TVRGbFppMWlPR1V3TFdJeFptRmpOR1ppWkRobU1TSjkuMzJzdU1DRDdTcHV0bGVNaEgwejltNWloYUxWM3BENUZreVFSZmhFcXRrMA==");
client.DefaultRequestHeaders.Add("referer", "https://www.santandernegocios.com.br/");
client.DefaultRequestHeaders.Add("sec-ch-ua", ""Not)A;Brand";v="99", "Google Chrome";v="127", "Chromium";v="127"");
client.DefaultRequestHeaders.Add("sec-ch-ua-mobile", "?0");
client.DefaultRequestHeaders.Add("sec-ch-ua-platform", ""Windows"");
client.DefaultRequestHeaders.Add("sec-fetch-dest", "empty");
client.DefaultRequestHeaders.Add("sec-fetch-mode", "cors");
client.DefaultRequestHeaders.Add("sec-fetch-site", "cross-site");
client.DefaultRequestHeaders.UserAgent.ParseAdd("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36");
client.DefaultRequestHeaders.Add("x-app-request-id", "2662302302923938");
client.DefaultRequestHeaders.Add("x-global-request-id", "f268211b-2801-66c6-d109-af73c4453a52");
var payload = new DocumentPayload
{
document = new DocumentPayload.Document
{
Number = "BcP8PuISnBkWfP/FWk3SQg==",
Type = 13
}
};
//options e post antes de pesquisar
string jsonPayload = JsonConvert.SerializeObject(payload);
var jsonContent = new StringContent(jsonPayload, Encoding.UTF8, "application/json");
response = await client.PostAsync("https://esbapi.santander.com.br/people/v3/person-code/by-document-number?gw-app-key=bfa4d8e04f460137b98e005056a171c8", jsonContent);
string responseBody = await response.Content.ReadAsStringAsync();
}
//continuando a sessao com os cookies do selenium
}
driver.Close();
}
}
private static async Task DeleteFiles()
{
string[] prefixes = { "REQUEST", "RESPONSE" };
Directory.GetFiles(documentsPath)
.Where(file => prefixes.Any(prefix => Path.GetFileName(file).StartsWith(prefix, StringComparison.OrdinalIgnoreCase)))
.ToList()
.ForEach(file =>
{
try
{
System.IO.File.Delete(file);
}
catch (Exception ex)
{
Console.WriteLine($"Failed to delete file: {file}. Exception: {ex.Message}");
}
});
}
private static Dictionary<string, List<string>> ReadFilesWithPrefix(string folderPath, string[] prefixes)
{
var fileContents = new Dictionary<string, List<string>>();
foreach (var prefix in prefixes)
{
var files = Directory.GetFiles(folderPath, $"{prefix}*.txt");
foreach (var file in files)
{
var content = System.IO.File.ReadAllText(file);
var lines = content.Contains("rn") ? content.Split(new[] { "rn" }, StringSplitOptions.None)
: content.Split('n');
fileContents[file] = new List<string>(lines);
}
}
return fileContents;
}
private static async Task HandleDevToolsEvent(object sender, DevToolsEventReceivedEventArgs e, string documentsPath, Counter counter, List<(string FileName, string Content)> logs)
{
if (e.EventName == "requestWillBeSentExtraInfo")
{
var requestHeaders = e.EventData["headers"];
string fileName = Path.Combine(documentsPath, $"RESPONSE_responseHeaders_{counter.Value}.txt");
logs.Add((fileName, requestHeaders.ToString()));
Console.WriteLine("REQUEST HEADERS: n" + requestHeaders);
}
if (e.EventName == "responseReceivedExtraInfo")
{
var responseHeaders = e.EventData["headers"];
string fileName = Path.Combine(documentsPath, $"REQUEST_requestHeaders_{counter.Value}.txt");
logs.Add((fileName, responseHeaders.ToString()));
Console.WriteLine("RESPONSE HEADERS: n" + responseHeaders);
counter.Increment();
}
}
private static async Task LoginAsync(ChromeDriver driver, string username, string password, string numCpfCnpj)
{
var usernameInput = new WebDriverWait(driver, TimeSpan.FromSeconds(7)).Until(ExpectedConditions.ElementToBeClickable((By.Id("userLogin__input"))));
var passwordInput = new WebDriverWait(driver, TimeSpan.FromSeconds(7)).Until(ExpectedConditions.ElementToBeClickable((By.Id("userPassword__input"))));
usernameInput.SendKeys(username);
passwordInput.SendKeys(password);
passwordInput.SendKeys(Keys.Enter);
var searchDado = new WebDriverWait(driver, TimeSpan.FromSeconds(7)).Until(ExpectedConditions.ElementToBeClickable(By.ClassName("search")));
var secondSearch = searchDado.FindElement(By.Name("inputSearch"));
secondSearch.SendKeys(numCpfCnpj);
secondSearch.SendKeys(Keys.Enter);
}
}