C# WebRequest удаляет заголовок авторизации по запросу GET - PullRequest
0 голосов
/ 11 января 2020

Я пытаюсь установить связь с каким-либо сервером, но при использовании запроса GET заголовок авторизации удаляется.

Мой код (прошу прощения за беспорядок):

public ApiResponse MakeApiRequest(string path, string body, Dictionary<string, string> header,
            Dictionary<string, string> query, string method)
{
    var queryBuilder = new StringBuilder("?");
    foreach (var queryPair in query)
    {
        queryBuilder.Append(queryPair.Key + "=" + queryPair.Value + "&");
    }

    var queryString = queryBuilder.ToString();
    queryString = queryString.Substring(0, queryString.Length - 1);

    var request = (HttpWebRequest) WebRequest.Create(new Uri(ApiServer + path + queryString));

    request.Timeout = 5000;
    request.UserAgent = "VSpedSync/DevBuild";
    request.Method = method;

    foreach (var headerPair in header)
    {
        if (headerPair.Key.ToLower().Equals("user-agent")) continue;
        if (headerPair.Key.ToLower().Equals("authorization"))
        {
            request.PreAuthenticate = true;
        }
        request.Headers.Add(headerPair.Key, headerPair.Value);
    }

    Debug.WriteLine("preauth "+request.PreAuthenticate);

    if (!body.Equals(""))
    {
        var stream = request.GetRequestStream();
        var streamWriter = new StreamWriter(stream);

        streamWriter.Write(body);

        streamWriter.Close();
    }

    HttpWebResponse response;
    try
    {
        response = (HttpWebResponse) request.GetResponse();
    }
    catch (WebException ex)
    {
        response = (ex.Response as HttpWebResponse);
        if (response == null)
            throw;
    }

    foreach (string requestHeader in request.Headers)
    {
        Debug.WriteLine(" --> "+requestHeader+": "+request.Headers.Get(requestHeader));
    }

    var statusCode = response.StatusCode;
    var responseHeaders = new Dictionary<string, string>();
    foreach (string headerKey in response.Headers)
    {
        var headerVal = response.Headers.Get(headerKey);
        responseHeaders.Add(headerKey, headerVal);
    }

    var responseBody = "NONE";
    try
    {
        var streamReader = new StreamReader(response.GetResponseStream());
        responseBody = streamReader.ReadToEnd();
    }
    catch (Exception)
    {
        responseBody = "ERROR";
        // ignored
    }

    return new ApiResponse(
        statusCode,
        responseBody,
        !responseBody.Equals("ERROR") && !responseBody.Equals("NONE"),
        responseHeaders
    );
}

Это Вот как я вызываю метод:

var apiResponse = api.MakeApiRequest("auth/check/", "", new Dictionary<string, string>()
{
    {"Authorization", "Bearer " + token.token},
    {"test", "f"}
}, new Dictionary<string, string>(), "GET");

Заголовки, отправляемые при использовании метода GET:

 --> User-Agent: VSpedSync/DevBuild
 --> test: f
 --> Host: localhost:55445

Заголовки, отправляемые при использовании метода POST:

 --> User-Agent: VSpedSync/DevBuild
 --> Authorization: Bearer xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
 --> test: f
 --> Host: localhost:55445

Я что-то не так делаю?

Редактировать: Кажется, будет решена. Сейчас я использую RestSharp вместо обычного WebRequest.

Ответы [ 2 ]

0 голосов
/ 12 января 2020

Вы можете попробовать использовать HttpClient вместо WebRequest. Я попробовал следующее, и заголовок авторизации остался в запросе после отправки.

const string ApiServer = "https://google.com";
static readonly HttpClient _httpClient = new HttpClient();

static async Task Main()
{
    InitializeClient();

    var headers = new Dictionary<string, string>()
    {
        { "Authorization", "Bearer e45jsh56" },
        { "Test", "test_value" }
    };

    var paramterers = new Dictionary<string, string>()
    {
        { "pageNum", "3" },
        { "pageSize", "100" }
    };

    var response = await MakeApiCallAsync("mypath", "request_body", headers, paramterers, "GET");

    Console.WriteLine($"Status Code: {response.StatusCode}.");
}

static void InitializeClient()
{
    //  Set the base URI
    _httpClient.BaseAddress = new Uri(ApiServer);

    //  Set Timeout to 5 seconds
    _httpClient.Timeout = new TimeSpan(hours: 0, minutes: 0, seconds: 5);

    //  Set the default User Agent
    _httpClient.DefaultRequestHeaders.UserAgent.ParseAdd("VSpedSync/DevBuild");
}

static async Task<ApiResponse> MakeApiCallAsync(string path, 
    string body, Dictionary<string, string> headers, 
    Dictionary<string, string> query, string method)
{
    //  Generate query string
    string queryString = '?' + 
        string.Join(separator: '&', values: query.Select(q => $"{q.Key}={q.Value}"));

    //  Create the relative URL
    string relativeUrl = path + queryString;

    //  Create the Http Method object
    HttpMethod httpMethod = new HttpMethod(method);

    //  Create the request object
    HttpRequestMessage request = new HttpRequestMessage(httpMethod, relativeUrl);

    //  Set headers to the request
    foreach (KeyValuePair<string, string> h in headers)
    {
        if (!h.Key.Equals("UserAgent", StringComparison.OrdinalIgnoreCase))
        {
            request.Headers.Add(h.Key, h.Value);
        }
    }

    //  Set the content of the request
    if (!string.IsNullOrEmpty(body))
    {
        request.Content = new StringContent(body);
    }

    //  Send the request
    HttpResponseMessage response = await _httpClient.SendAsync(request);

    //  Display request headers
    foreach(var h in request.Headers)
    {
        Console.WriteLine($" --> {h.Key}: {string.Join(';', h.Value)}.");
    }

    //  Process the response body
    string responseBody = "NONE";

    try
    {
        //  Read the content as a string
        responseBody = await response.Content.ReadAsStringAsync();
    }
    catch
    {
        responseBody = "ERROR";
    }

    //  Return the api response
    return new ApiResponse
    {
        StatusCode = response.StatusCode,
        ResponseBody = responseBody,
        ValidResponse = !responseBody.Equals("NONE") && !responseBody.Equals("ERROR"),
        ResponseHeaders = response.Headers.ToDictionary(h => h.Key, h => string.Join(';', h.Value)),
    };
}

Вывод

 --> Authorization: Bearer e45jsh56.
 --> Test: test_value.
 --> User-Agent: VSpedSync/DevBuild.
Status Code: BadRequest.
0 голосов
/ 11 января 2020

Возможно, попробуйте использовать метод перегрузки WebHeaderCollection.Add(HttpRequestHeader, String).

public static ApiResponse MakeApiRequest(string path, string body, Dictionary<string, string> headers,
    Dictionary<string, string> query, string method)
{
    //  Generate the query string
    string queryString = '?' +
        string.Join(separator: '&', values: query.Select(q => $"{q.Key}={q.Value}"));

    //  Create request obejct
    HttpWebRequest request = (HttpWebRequest)WebRequest.Create(new Uri(ApiServer + path + queryString));

    request.Timeout = 5000;
    request.UserAgent = "VSpedSync/DevBuild";
    request.Method = method;

    //  Set headers to the request
    foreach (KeyValuePair<string, string> h in headers)
    {
        if (h.Key.Equals("Authorization", StringComparison.OrdinalIgnoreCase))
        {
            request.Headers.Add(HttpRequestHeader.Authorization, h.Value);
        }

        else if (!h.Key.Equals("UserAgent", StringComparison.OrdinalIgnoreCase))
        {
            request.Headers.Add(h.Key, h.Value);
        }
    }

    foreach (string requestHeader in request.Headers)
    {
        Debug.WriteLine(" --> " + requestHeader + ": " + request.Headers.Get(requestHeader));
    }

    // ...
    // .... Continue ....
    // ...
    return null;
}
...