【问题标题】:how to send a http basic auth post?如何发送 http 基本身份验证帖子?
【发布时间】:2014-01-30 17:49:40
【问题描述】:

我的任务是使用基本身份验证创建一个 http 帖子。 我正在用 C# 在 asp.net MVC 应用程序中进行开发。

我也得到了这个例子。

{
POST /v2/token_endpoint HTTP/1.1
Authorization: Basic Y2xpZW50X2lkOmNsaWVudF9zZWNyZXQ=
Accept: application/json
Content-Type: application/x-www-form-urlencoded
User-Agent: Java/1.6.0_33
Host: api.freeagent.com
Connection: close
Content-Length: 127

grant_type=authorization_code&code=12P3AsFZXwXjd7SLOE1dsaX8oCgix&redirect_uri=http%3A%2F%2Flocalhost%3A8080%2Foauth
}

我的问题是如何在 C# 中编写代码? 如果需要更多信息,请询问,提前谢谢

编辑:我已经取得了一些进展,但我还没有添加grant_type

public void AccessToken(string code)
    {
        string url = @"https://api.freeagent.com/v2/token_endpoint";
        WebClient client = new WebClient();
        string credentials = Convert.ToBase64String(Encoding.ASCII.GetBytes(ApiKey + ":" + ApiSecret));
        client.Headers[HttpRequestHeader.Authorization] = "Basic " + credentials;
        client.Headers[HttpRequestHeader.Accept] = "application/json";
        client.Headers[HttpRequestHeader.ContentType] = "application/x-www-form-urlencoded";
        client.Headers[HttpRequestHeader.UserAgent] = "Java/1.6.0_33";
        client.Headers[HttpRequestHeader.Host] = "api.freeagent.com";
        client.Headers[HttpRequestHeader.Connection] = "close";
        client.Headers["grant_type"] = "authorization_code";

        var result = client.DownloadString(url);
    }

那么我该如何在帖子中添加:grant_type=authorization_code&code=12P3AsFZXwXjd7SLOE1dsaX8oCgix&redirect_uri=http%3A%2F%2Flocalhost%3A8080%2Foauth?

【问题讨论】:

    标签: c# asp.net http post


    【解决方案1】:

    我也曾为此苦苦挣扎,但我现在已经走到了另一边!

    最让我难过的是,如果您在 Auth Token 请求中指定了重定向 URL,那么您还必须在 Access Token 请求中指定它使用相同的 URL,即使它是没用过。

    我从某人的部分包装器开始,并且已经将它发展得几乎面目全非。希望这个包装器(完整的身份验证和访问令牌代码)将帮助其他人。到目前为止,我只用它来创建发票和发票项目,其他功能未经测试,但它应该可以为您提供令牌并可以调试请求。

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Net;
    using System.Text;
    using System.Web.Script.Serialization;
    
    namespace ClientZone.External
    {
        public class FreeAgent
        {
            public enum Methods
            {
                POST = 1,
                PUT
            }
    
            public enum Status
            {
                Draft = 1,
                Sent,
                Cancelled
            }
    
            private string _subDomain;
            private string _identifier;
            private string _secret;
            private string _redirectURI;
            public static string AuthToken = "";
            private static string _accessToken = "";
            private static string _refreshToken = "";
            private static DateTime _refreshTime;
    
            public FreeAgent(string identifier, string secret, string subdomain, string redirectURI)
            {
                _subDomain = subdomain;
                _identifier = identifier;
                _secret = secret;
                _redirectURI = redirectURI; // If this was specified in the Auth Token call, you must specify it here, and it must be the same
            }
    
            public bool GetAccessToken()
            {
                try
                {
                    string url = @"https://api.freeagent.com/v2/token_endpoint";
                    WebClient client = new WebClient();
                    string credentials = Convert.ToBase64String(Encoding.ASCII.GetBytes(_identifier + ":" + _secret));
                    client.Headers[HttpRequestHeader.Host] = "api.freeagent.com";
                    client.Headers[HttpRequestHeader.KeepAlive] = "true";
                    client.Headers[HttpRequestHeader.Accept] = "application/json";
                    client.Headers[HttpRequestHeader.UserAgent] = "Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.93 Safari/537.36";
                    client.Headers[HttpRequestHeader.ContentType] = "application/x-www-form-urlencoded;charset=UTF-8";
    
                    client.Headers[HttpRequestHeader.Authorization] = "Basic " + credentials;
                    System.Net.ServicePointManager.Expect100Continue = false;
                    client.Headers[HttpRequestHeader.AcceptEncoding] = "gzip, deflate";
                    client.Headers[HttpRequestHeader.AcceptLanguage] = "en-US,en;q=0.8";
    
                    var result = "";
                    if (!(_accessToken == "" && _refreshToken != ""))
                    {
                        string data = string.Format("grant_type=authorization_code&code={0}&redirect_uri={1}", AuthToken, _redirectURI);
                        result = client.UploadString(url, data);
                    }
                    else
                    {
                        // Marking the access token as blank and the refresh token as not blank
                        // is a sign we need to get a refresh token
                        string data = string.Format("grant_type=refresh_token&refresh_token={0}", _refreshToken);
                        result = client.UploadString(url, data);
                    }
    
                    JavaScriptSerializer json_serializer = new JavaScriptSerializer();
                    var results_list = (IDictionary<string, object>)json_serializer.DeserializeObject(result);
                    _accessToken = results_list["access_token"].ToString();
                    int secondsUntilRefresh = Int32.Parse(results_list["expires_in"].ToString());
                    _refreshTime = DateTime.Now.AddSeconds(secondsUntilRefresh);
                    if (results_list.Any(x => x.Key == "refresh_token"))
                    {
                        _refreshToken = results_list["refresh_token"].ToString();
                    }
    
                    if (_accessToken == "" || _refreshToken == "" || _refreshTime == new DateTime())
                    {
                        return false;
                    }
    
                }
                catch
                {
                    return false;
                }
    
                return true;
            }
    
            private HttpStatusCode SendWebRequest(Methods method, string URN, string request, out string ResponseData)
            {
                if (_accessToken == "")
                {
                    // The access token has not been retrieved yet
                    GetAccessToken();
                }
                else
                {
                    if (_refreshTime != new DateTime() && _refreshTime < DateTime.Now) {
                        // The token has expired and we need to refresh it
                        _accessToken = "";
                        GetAccessToken();
                    }
                }
    
                if (_accessToken != "")
                {
                    try
                    {
                        WebClient client = new WebClient();
                        string url = "https://api.freeagentcentral.com/v2/" + URN;
                        client.Headers[HttpRequestHeader.UserAgent] = "Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.93 Safari/537.36";
                        client.Headers[HttpRequestHeader.Authorization] = "Bearer " + _accessToken;
                        client.Headers[HttpRequestHeader.ContentType] = "application/json";
                        client.Headers[HttpRequestHeader.Accept] = "application/json";
    
                        if (method == Methods.POST || method == Methods.PUT)
                        {
                            string data = request;
                            var result = client.UploadString(url, method.ToString(), data);
                            ResponseData = result;
                            return HttpStatusCode.Created;
                        }
                        else
                        {
                            var result = client.DownloadString(url);
                            ResponseData = result;
                            return HttpStatusCode.OK;
                        }
                    }
                    catch (WebException e)
                    {
                        if (e.GetType().Name == "WebException")
                        {
                            WebException we = (WebException)e;
                            HttpWebResponse response = (System.Net.HttpWebResponse)we.Response;
    
                            ResponseData = response.StatusDescription;
                            return response.StatusCode;
                        }
                        else
                        {
                            ResponseData = e.Message;
                            if (e.InnerException != null)
                            {
                                ResponseData = ResponseData + " - " + e.InnerException.ToString();
                            }
                            return HttpStatusCode.SeeOther;
                        }
                    }
                }
                else
                {
                    ResponseData = "Access Token could not be retrieved";
                    return HttpStatusCode.SeeOther;
                }
            }
    
            private int ExtractNewID(string resp, string URN)
            {
                if (resp != null && resp.Trim() != "")
                {
                    JavaScriptSerializer json_serializer = new JavaScriptSerializer();
                    var results_list = (IDictionary<string, object>)json_serializer.DeserializeObject(resp);
    
                    if (results_list.Any(x => x.Key == "invoice"))
                    {
                        var returnInvoice = (IDictionary<string, object>)results_list["invoice"];
    
                        if (returnInvoice["created_at"].ToString() != "")
                        {
                            string returnURL = returnInvoice["url"].ToString();
    
                            if (returnURL.Contains("http"))
                            {
                                return int.Parse(returnURL.Remove(0, ("https://api.freeagentcentral.com/v2/" + URN).Length + 1));
                            }
                            else
                            {
                                return int.Parse(returnURL.Remove(0, URN.Length + 2));
                            }
                        }
                    }
                }
    
                return -1;
            }
    
            public int CreateContact(string firstName, string lastName, string emailAddress, string street, string city, string state, string postcode, string country)
            {
                StringBuilder request = new StringBuilder();
    
                request.Append("{\"contact\":{");
                request.Append("\"first-name\":");
                request.Append(firstName);
                request.Append("\",");
                request.Append("\"last-name\":");
                request.Append(lastName);
                request.Append("\",");
                request.Append("\"email\":");
                request.Append(emailAddress);
                request.Append("\",");
    
                request.Append("\"address1\":");
                request.Append(street);
                request.Append("\",");
                request.Append("\"town\":");
                request.Append(city);
                request.Append("\",");
                request.Append("\"region\":");
                request.Append(state);
                request.Append("\",");
                request.Append("\"postcode\":");
                request.Append(postcode);
                request.Append("\",");
                request.Append("\"country\":");
                request.Append(country);
                request.Append("\"");
    
                request.Append("}");
    
                string returnData = string.Empty;
    
                HttpStatusCode responseCode = SendWebRequest(Methods.POST, "contacts", request.ToString(), out returnData);
                if (responseCode == HttpStatusCode.OK || responseCode == HttpStatusCode.Created)
                {
                    return ExtractNewID(returnData, "contacts");
                }
                else
                {
                    return -1;
                }
            }
    
            public int CreateInvoice(int contactID, DateTime invoiceDate, int terms, string reference, string comments, string currency = "GBP")
            {
                StringBuilder request = new StringBuilder();
    
                request.Append("{\"invoice\":{");
                request.Append("\"dated_on\": \"");
                request.Append(invoiceDate.ToString("yyyy-MM-ddTHH:mm:00Z"));
                request.Append("\",");
    
                if (!string.IsNullOrEmpty(reference))
                {
                    request.Append("\"reference\": \"");
                    request.Append(reference);
                    request.Append("\",");
                }
    
                if (!string.IsNullOrEmpty(comments))
                {
                    request.Append("\"comments\": \"");
                    request.Append(comments);
                    request.Append("\",");
                }
    
                request.Append("\"payment_terms_in_days\": \"");
                request.Append(terms);
                request.Append("\",");
    
                request.Append("\"contact\": \"");
                request.Append(contactID);
                request.Append("\",");
    
                if (currency == "EUR")
                {
                    request.Append("\"ec_status\": \"");
                    request.Append("EC Services");
                    request.Append("\",");
                }
    
                request.Append("\"currency\": \"");
                request.Append(currency);
                request.Append("\"");
    
                request.Append("}}");
    
                string returnData = string.Empty;
    
                HttpStatusCode responseCode = SendWebRequest(Methods.POST, "invoices", request.ToString(), out returnData);
                if (responseCode == HttpStatusCode.OK || responseCode == HttpStatusCode.Created)
                {
                    return ExtractNewID(returnData, "invoices");
                }
                else
                {
                    return -1;
                }
            }
    
            public bool ChangeInvoiceStatus(int invoiceID, Status status)
            {
                string returnData = string.Empty;
    
                HttpStatusCode resp = SendWebRequest(Methods.PUT, "invoices/" + invoiceID.ToString() + "/transitions/mark_as_" + status.ToString().ToLower(), string.Empty, out returnData);
    
                return false;
            }
    
            public int CreateInvoiceItem(int invoiceID, string itemType, float price, int quantity, float taxRate, string description)
            {
                StringBuilder request = new StringBuilder();
    
                request.Append("{\"invoice\":{");
                request.Append("\"invoice_items\":[{");
    
                request.Append("\"item_type\": \"");
                request.Append(itemType);
                request.Append("\",");
    
                request.Append("\"price\": \"");
                request.Append(price.ToString("0.00"));
                request.Append("\",");
    
                request.Append("\"quantity\": \"");
                request.Append(quantity);
                request.Append("\",");
    
                request.Append("\"sales_tax_rate\": \"");
                request.Append(taxRate.ToString("0.00"));
                request.Append("\",");
    
                request.Append("\"description\": \"");
                request.Append(description);
                request.Append("\"");
    
                request.Append("}]");
                request.Append("}");
                request.Append("}");
    
                string returnData = string.Empty;
    
                HttpStatusCode responseCode = SendWebRequest(Methods.PUT, "invoices/" + invoiceID.ToString(), request.ToString(), out returnData);
                if (responseCode == HttpStatusCode.OK || responseCode == HttpStatusCode.Created)
                {
                    // Invoice items is an update call to an invoice, so we just get a 200 OK with no response body to extract an ID from
                    return 0;
                }
                else
                {
                    return -1;
                }
            }
        }
    }
    

    要在 MVC 设置中使用它,您需要在索引中检测是否需要登录。如果是,您告诉 FreeAgent 返回另一个 ActionResult(我使用了 Auth)来捕获重定向并存储代码。

        public ActionResult Index()
        {
            if (MyNamespace.External.FreeAgent.AuthToken == "")
            {
                return Redirect("https://api.freeagent.com/v2/approve_app?redirect_uri=" + Request.Url.Scheme + "://" + Request.Url.Authority + "/Invoice/Auth" + "&response_type=code&client_id=1234567890123456789012");
    
            }
            else
            {
                return View();
            }
        }
    
    
        public ActionResult Auth()
        {
            if (Request.Params.Get("code").ToString() != "")
            {
                ClientZone.External.FreeAgent.AuthToken = Request.Params.Get("code").ToString();
            }
    
            return View("Index");
        }
    

    那么你需要的功能就是

    MyNameSpace.External.FreeAgent FA = new ClientZone.External.FreeAgent("abcdefghhijklmnopqrstu", "1234567890123456789012", "acme", "http://localhost:52404/Invoice/Auth");
    
    int newID = FA.CreateInvoice(54321, InvoiceDate, 30, "", "", "GBP");
    if (newID != -1)
    {
        FA.CreateInvoiceItem(newID, unit, rate, quantity, number, description);
    }
    

    CreateInvoice 中有一些英国/欧盟特定的编码。我不确定这是多么自定义或标准,但我将其保留,因为删除它比重新创建它更容易。

    【讨论】:

      【解决方案2】:

      您可以在这里找到如何使用 WebRequest 和 WebClient 类发出基本身份验证请求的两个示例:

      http://grahamrhay.wordpress.com/2011/08/22/making-a-post-request-in-c-with-basic-authentication/ http://anishshenoy57.wordpress.com/2013/01/22/basic-http-authentication-using-c/

      基本的认证就是Base64(username:password),所以很容易实现。

      更新1

      这是基于您的方法的示例:

      public void AccessToken(string code)
      {
          string url = @"https://api.freeagent.com/v2/token_endpoint";
          WebClient client = new WebClient();
          string credentials = Convert.ToBase64String(Encoding.ASCII.GetBytes(ApiKey + ":" + ApiSecret));
          client.Headers[HttpRequestHeader.Authorization] = "Basic " + credentials;
          client.Headers[HttpRequestHeader.Accept] = "application/json";
          client.Headers[HttpRequestHeader.ContentType] = "application/x-www-form-urlencoded";
          client.Headers[HttpRequestHeader.UserAgent] = "Java/1.6.0_33";
          client.Headers[HttpRequestHeader.Host] = "api.freeagent.com";
          client.Headers[HttpRequestHeader.Connection] = "close";
          client.Headers["grant_type"] = "authorization_code";
      
          string data = string.Format(
              "grant_type=authorization_code&code={0}&redirect_uri=http%3A%2F%2Flocalhost%3A8080",
              code);
          var result = client.UploadString(url, data);
      }
      

      WebClient中唯一的调用方法不同。 DownloadString 将执行GET 请求,但对于POST,您需要使用UploadString 方法

      【讨论】:

      • 对不起,但这些似乎都没有解决方案来显示如何在发布请求中发送上述所有信息:s
      • 我已经根据您的 AccessToken 方法和 POST 请求更新了示例
      猜你喜欢
      • 2015-05-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-10-19
      • 2021-03-21
      • 2011-11-12
      • 2011-05-05
      • 1970-01-01
      相关资源
      最近更新 更多