QuickBooks Online Oauth2令牌请求产生"错误请求"

时间:2018-01-31 01:53:14

标签: vb.net oauth-2.0 quickbooks-online

在尝试将用VB编写的.NET应用程序与qbo(quickbooks online)链接起来时,我一直在与Oauth2进行斗争。我可以得到我的代码,但我得到了一个"(400)Bad Request"尝试交换代码以进行访问和刷新令牌时的响应。这是我的请求访问令牌的代码:

Function GetTokens(strCode As String, strURL As String, strClientID As String, strClientSecret As String, strRedirectURI As String) As Boolean
    Dim strBasic, strPostData As String
    Dim strResponse As String
    strBasic = strClientID & ":" & strClientSecret
    Dim byt As Byte() = System.Text.Encoding.UTF8.GetBytes(strBasic)
    strBasic = Convert.ToBase64String(byt)
    strPostData = "grant_type=authorization_code"
    strPostData += "&code=" & strCode
    strPostData += "&redirect_uri=" & strRedirectURI
    strResponse = ReadURLwithAuthentication("POST", strURL, strPostData, strBasic)
    Response.Write(strResponse)
    Return True
End Function

    Function ReadURLwithAuthentication(strMethod As String, strURL As String, strPostData As String, strToken As String) As String
        Dim wrX As WebRequest = WebRequest.Create(strURL)
        'request method
        wrX.Method = strMethod
        'protocal version
        CType(wrX, HttpWebRequest).ProtocolVersion = HttpVersion.Version11
        'accept
        CType(wrX, HttpWebRequest).Accept = "application/json"
        'authorization
        wrX.Headers.Add("Authorization", "Basic " + strToken)
        'content type
        wrX.ContentType = "application/x-www-form-urlencoded"
        'host
        CType(wrX, HttpWebRequest).Host = "oauth.platform.intuit.com"
        'contentbody only supplied for POST
        Select Case strMethod
            Case "POST", "DELETE"
                'convert post data to a byte array.
                Dim byteArray As Byte() = Encoding.UTF8.GetBytes(strPostData)
                'content length
                wrX.ContentLength = byteArray.Length
                'get the stream that holds the request
                Dim smX As Stream = wrX.GetRequestStream()
                'write the data to the stream object
                smX.Write(byteArray, 0, byteArray.Length)
                'close the stream
                smX.Close()
        End Select
        'get the response object
        Dim strResponse As String
        Try
            Dim respX As WebResponse = wrX.GetResponse()
            'get response stream
            Dim smY As Stream = respX.GetResponseStream
            'examine the results
            Dim encode As Encoding = System.Text.Encoding.GetEncoding("utf-8")
            Dim sw As New StreamReader(smY, encode)
            strResponse = sw.ReadToEnd
            'close stream
            smY.Close()
            'close the response object
            respX.Close()
            'close stream reader
            sw.Close()
        Catch ex As Exception
            strResponse = ex.Message.ToString
        End Try
        Return strResponse
    End Function

2 个答案:

答案 0 :(得分:1)

错误请求几乎肯定意味着您发送的数据无效。因此,解决问题的最简单方法是获取请求和响应的日志并进行分析。请求应该与OAuth2 RFC中的请求类似。

但是看一下你的代码,我发现有一件事可能导致问题 - 你发送了一个application/x-www-form-urlencoded内容类型的请求,但你没有对其数据进行编码。如果值(auth code或redirectUri)包含诸如&符号&之类的字符,则会无意中引入新的请求参数(&something=)并使原始值无效。所以你的代码应该是这样的:

strPostData = "grant_type=authorization_code"
strPostData += "&code=" & HttpUtility.UrlEncode(strCode)
strPostData += "&redirect_uri=" & HttpUtility.UrlEncode(strRedirectURI)

ReadURLwithAuthentication方法中,Case "POST", "DELETE"可能适用于POSTPUT方法,因为DELETE请求不能包含正文。< / p>

答案 1 :(得分:0)

It turns out the main problem was that I was submitting two different redirect_uri's. Since Jan Halasa kindly provided the link to the OAuth2 RFC, I learned that the redirect_uri has to be exactly the same for the code request and the follow-up token request. The httputility.encode() was not necessary since my redirect_uri did not include any ampersands or other special characters.