XSRF-Token

DataKnight11

Member
Joined
Apr 18, 2024
Messages
16
Location
Portugal
Programming Experience
Beginner
Hello community,

How is it possible to make http request for login in C#?
When I try to make the http request with the POST protocol I cannot obtain the XSRF-TOKEN.
Can anyone help me?



var loginData = new { userName = username, systemCode = password };
var requestBody = new StringContent(JsonConvert.SerializeObject(loginData), Encoding.UTF8, "application/json");



HttpResponseMessage response = await _httpClient.PostAsync(url, requestBody);
Console.WriteLine($"Status Code: {response.StatusCode}");
LogResponseDetails(response);
 
I think that you'll need to attach a cookie container to a HttpClientHandler and then initialize your HttpClient with that client handler. Then after your initial logon, you'lll need to copy the cookie value out of the cookie container and put it into your request headers.
 
Still not working

C#:
    public class NetworkService : INetworkService
    {
        private readonly HttpClient _webClient;
        private readonly CookieContainer _cookieManager;
        private readonly HttpClientHandler _webHandler;

        public NetworkService(IHttpClientFactory clientFactory)
        {
            _cookieManager = new CookieContainer();
            _webHandler = new HttpClientHandler()
            {
                SslProtocols = SslProtocols.Tls12 | SslProtocols.Tls13,
                MaxAutomaticRedirections = 10,
                UseCookies = true,
                CookieContainer = _cookieManager,
                AllowAutoRedirect = true,
                CheckCertificateRevocationList = true
            };

            _webClient = clientFactory.CreateClient("NetworkServiceClient");
            _webClient.BaseAddress = new Uri("[URL]https://example.com/api[/URL]");
            _webClient.DefaultRequestHeaders.Accept.Clear();
            _webClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
        }

        public async Task<string> CallApi1(string userId, string accessCode)
        {
            var endpoint = new Uri(_webClient.BaseAddress, "/api1/login");
            var loginInfo = new { userName = username, userPassword = password };
            var contentBody = new StringContent(JsonConvert.SerializeObject(loginInfo), Encoding.UTF8, "application/json");

            HttpResponseMessage result = await _webClient.PostAsync(endpoint, contentBody);
            if (!result.IsSuccessStatusCode)
            {
                Console.WriteLine($"API1 call failed with status code: {result.StatusCode}");
                return null;
            }

            var token = ExtractCookie("XSRF-TOKEN");
            return token;
        }
    }
 
Last edited by a moderator:
What is not working? What error are you getting? Which line is causing the error? What does the documentation for the login API say?
 
What is not working? What error are you getting? Which line is causing the error? What does the documentation for the login API say?

The code is functioning properly and returns a 200 response, however, I’m not receiving the XSRF Cookie. When I perform the HTTP request in Postman, I do receive the XSRF Cookie. But in C#, it’s not being received.
 
You did not show your code for ExtractCookie(). Did you step through that code to see what cookies are returned?

Also, did you look at the HTTP headers of the response?
 
Also are you sure it is suppose to be "XSRF-TOKEN" or is it "CSRF-TOKEN"?
 
You did not show your code for ExtractCookie(). Did you step through that code to see what cookies are returned?

Also, did you look at the HTTP headers of the response?
Indeed, I am verifying all the values in the responses, but I’m not finding anything.
The headers contain only one cookie, which is the session ID. It’s not something I desire, but it’s expected, just like the response I receive in Postman. So i should receive the session id and the XSRF-TOKEN

XSRF:
            var token = GetCookieValueFromResponse(response, "XSRF-TOKEN");
            if (string.IsNullOrEmpty(token))
            {
                Debug.WriteLine("XSRF-TOKEN not found in cookies after successful authentication.");
            }
            return token;
        }

        private string GetCookieValueFromResponse(HttpResponseMessage response, string cookieName)
        {
            if (response.Headers.TryGetValues("Set-Cookie", out var cookies))
            {
                foreach (var cookie in cookies)
                {
                    if (cookie.StartsWith(cookieName))
                    {
                        return cookie.Split(new[] { '=' }, 2)[1].Split(';')[0];
                    }
                }
            }
            return null;
        }
 
What did you find in the cookie container?

If you compare your code's sent headers and body to the postman headers and body, are there any major differences?
 
What did you find in the cookie container?

If you compare your code's sent headers and body to the postman headers and body, are there any major differences?

No, all I need to do is send the URL, use the POST method, and include the username and password in the body. However, the response I get is quite different. In Postman, I receive 26 values in the header, but in C#, I only get 22 values. I’m not sure why these differences occur, as I haven’t made any changes in Postman, is a default request.
 
This is why I was asking about the headers sent by Postman as compared to headers sent by your code. It's possible PostMan is filling in other header values like the agent name or some other thing.

As an aside that may or may not related, I was reading on SO that Headers.GetValues() may send results back in a disjointed manner, and that the best thing to do is to let the cookie container do the parsing and pulling out of values. Also there was an interesting response indicating that some other cookie values were being set in a series of redirects before finally getting the response.. They ended up disable auto redirects to be able to get those values straight from the headers.
 
Uh-oh! If you're using .NET (Core) then it gets even more interesting:

(It was also a blast from the past to see a few posts from davidsh on that issue. I used to work for him years ago during the Win95 days.)
 
Back
Top Bottom