简体   繁体   English

为什么我的 web 请求授权失败,但相同的请求在 python 和 postman 中有效?

[英]Why is my web request failing authorization, but the same request works in python and postman?

I have been having some issues with my internet recently.我最近在上网时遇到了一些问题。 Looks to be at the modem, or before the modem (on my ISP's side).看起来在调制解调器上,或者在调制解调器之前(在我的 ISP 这边)。 I want to record the logs and connection metrics.我想记录日志和连接指标。 I quickly tested logging in using python and postman.我使用 python 和 postman 快速测试了登录。 Now I want to swap to c# since that is what I am comfortable with, but things aren't working.现在我想换成 c#,因为这是我很满意的,但事情不正常。

In python and postman I have to send two requests for it to work.在 python 和 postman 中,我必须发送两个请求才能使其工作。 The first passes auth, and the second works.第一个通过身份验证,第二个有效。 In python I had to swap to Session instead of Request because two consecutive requests would fail.在 python 我不得不换成Session而不是Request因为两个连续的请求会失败。 So I'm thinking it has something to do with a cookie or something?所以我认为它与饼干或其他东西有关? However, postman shows no cookies being stored.但是,postman 显示没有存储 cookies。 I do not usually make web requests when working with c# so this may be a simple (dumb) issue.在使用 c# 时,我通常不会发出 web 请求,所以这可能是一个简单(愚蠢)的问题。 How can I emulate this session behavior in c#?如何在 c# 中模拟此 session 行为?

I call Get() twice, to mirror python and postman taking two requests to work, but both requests fail here.我调用Get()两次,镜像 python 和 postman 接受两个请求,但两个请求都失败了。 Below is my c# code and below that is the python code.下面是我的 c# 代码,下面是 python 代码。 Obviously these are dummy credentials.显然,这些是虚拟凭据。

public static class ModemMonitor
{
    public static string Get()
    {
        string result = "";

        Uri BaseUri = new Uri("http://192.168.100.1/");
        // I have tried all of the below auth strings and methods.
        // All give a 401 not authorized.
        string username = "admin";
        string password = "password";
        string auth = System.Convert.ToBase64String(Encoding.Default.GetBytes(username + ":" + password));
        string encoded = System.Convert.ToBase64String(System.Text.Encoding.GetEncoding("ISO-8859-1").GetBytes(username + ":" + password));

        try
        {
            var request = HttpWebRequest.CreateHttp(BaseUri);
            request.Headers.Add("authorization", auth);
            request.PreAuthenticate = true;
            request.Method = WebRequestMethods.Http.Get;
            HttpWebResponse response = (HttpWebResponse)request.GetResponse();
            using(StreamReader reader = new StreamReader(response.GetResponseStream()))
            {
                result += reader.ReadToEnd();
            }
        }
        catch (WebException webEx) { result += webEx.Message; }
        catch (Exception ex) { result += ex.Message; }

        return result;
    }
}

Working python code.工作 python 代码。

import requests
from requests import Session

session = requests.Session()
session.auth = ('admin', 'password')
baseUrl = 'http://192.168.100.1/'

auth = session.get(baseUrl)
response = session.get(baseUrl + 'eventLog.htm')
print(response.text)

You said it yourself that postman need two calls.你自己说 postman 需要两次调用。 The first one to create the token and the second to make your request.第一个创建令牌,第二个发出请求。

  1. Create the token创建令牌
       public async Task<AuthenticateUser> Authenticate(string username, string password)
        {
            var data = new FormUrlEncodedContent(new[]
            {
                new KeyValuePair<string,string>("grant_type","password"),
                new KeyValuePair<string,string>("username",username),
                new KeyValuePair<string,string>("password",password),
            });


            using (HttpResponseMessage response = await _ApiClient.PostAsync("/Token", data))
            {
                if (response.IsSuccessStatusCode)
                {
                    var result = await response.Content.ReadAsAsync<AuthenticateUser>();
                    return result;
                }
                else
                {
                    throw new Exception(response.ReasonPhrase);
                }
            }
        }

  1. Use the token to call the api使用令牌调用api
   public async Task GetLoggedInUserInfo(string token)
        {
            _ApiClient.DefaultRequestHeaders.Clear();
            _ApiClient.DefaultRequestHeaders.Accept.Clear();
            _ApiClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
            _ApiClient.DefaultRequestHeaders.Add("Authorization", $"Bearer { token}");

            using (HttpResponseMessage response = await _ApiClient.GetAsync("/api/user"))
            {
                if (response.IsSuccessStatusCode)
                {
                    var result = await response.Content.ReadAsAsync<LoggedInUserModel>();

                    
                   
                }
                else
                {
                    throw new Exception(response.ReasonPhrase);
                }
            }
        }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM