0

When I do a simple web request to this URL using the the WebClient Object (or any standard HTTP request method using the .NET framework), I get a 400 Bad Request Error. When I tried with CURL, I get a valid response from the web server. It seems like Google doesn't like a windows request - something throws it off.

It works in https://developers.google.com/oauthplayground/ and it also works if I just create a web form and do a post - I get an access token back no problem.

But I do need to be able to do it programmatically. I also tried WebRequest and HTTP object but did not really have a luck working with them yet.

I found about 4-5 similar questions here and some of them have a code examples - I tried their code but had no luck. (Code that I have tried)

Function GetAccessToken(ByVal Code As String, ByVal sScopes As String) As ActionResult Dim sAccessURLTokenURL As String = "https://accounts.google.com/o/oauth2/token"

Dim oWebCLient As New WebClient

Dim oNameValueCollection As New NameValueCollection

Dim oResponse() As Byte

oWebCLient.Headers.Add("Content-type", "application/x-www-form-urlencoded; charset=utf-8")

oNameValueCollection.Add("client_id", "562344623411-b2mt2215qdfs34asdqwe345jmq2ec7su.apps.googleusercontent.com")
oNameValueCollection.Add("client_secret", "KjsPkBUTosdeROuVfkKBaAwm")
oNameValueCollection.Add("code", Code)
oNameValueCollection.Add("scopes", sScopes)
oNameValueCollection.Add("grant_type", "authorization_code")

oResponse = oWebCLient.UploadValues(sAccessURLTokenURL, oNameValueCollection)

End Function

What am I doing wrong here?

Update

Got it to work!

Will Clean Up The Code And Post It With Some Explanations

Community
  • 1
  • 1
Alexey Shevelyov
  • 926
  • 1
  • 13
  • 24

2 Answers2

0

I guess you should set method and content type because the server response indicates that: bad request. So, I guess setting content type to application/x-www-form-urlencoded; charset=utf-8and method to POST will work. To do that:

oWebCLient.Headers.Add("Content-type", "application/x-www-form-urlencoded; charset=utf-8")
oWebClient.UploadValues(sAccessURLTokenURL, "POST", oNameValueCollection)

Webclient, as far as I know, uses GET as default method so I think is the problem you are facing... Could you try it please?

UPDATE

Also try:

oWebClient.Encoding = System.Text.Encoding.UTF8
oWebClient.Proxy = Nothign

Content type is not neede to be set if you use UploadValuesbecause it will be set to application/x-www-form-urlencoded automatically. It's not clear in docs that charset can be set through headers. Also if Google server detect an invalid parameter automatically will return a Bad Request so you probably have an error in parameters or calling uri, Could you please paste full code that doesn't works? Maybe I could be able to help you better.

Hope it helps!

ZeroWorks
  • 1,618
  • 1
  • 18
  • 22
0
Imports System.Web
Imports System.IO
Imports System.Net

Imports System.Text

Public Class OAuth2Utilities

Protected msTokenAuthorizationURL As String = "https://accounts.google.com/o/oauth2/token"

Public Function ExchangeAuthorizationCodeForTokens(ByVal oAuth2Model As oAuth2Model) As String
    Dim oWebResponse As WebResponse
    Dim sWebResponse As String

    If Not oAuth2Model Is Nothing Then

        oWebResponse = GetWebResponse(oAuth2Model)

        If Not oWebResponse Is Nothing Then

            sWebResponse = ReadWebResponse(oWebResponse)

        End If

    End If

    Return sWebResponse
End Function

Protected Function GetWebResponse(ByVal oAuth2Model As oAuth2Model) As WebResponse
    Dim oWebResponse As WebResponse = Nothing

    Dim oWebRequest As WebRequest

    Dim sRequestParameters As String
    Dim oRequestParametersByteArray() As Byte

    Dim oUTF8Encoding As New UTF8Encoding()

    Dim oStream As Stream

    If Not oAuth2Model Is Nothing Then

        oWebRequest = WebRequest.Create(msTokenAuthorizationURL)

        oWebRequest.Method = "POST"
        oWebRequest.ContentType = "application/x-www-form-urlencoded"

        sRequestParameters = String.Format("code={0}&client_id={1}&client_secret={2}&redirect_uri={3}&grant_type=authorization_code", oAuth2Model.AuthorizationCode, oAuth2Model.ClientID, oAuth2Model.ClientSecret, oAuth2Model.RedirectURI)

        oRequestParametersByteArray = oUTF8Encoding.GetBytes(sRequestParameters)

        If oRequestParametersByteArray.Length > 0 Then

            oWebRequest.ContentLength = oRequestParametersByteArray.Length

            oStream = oWebRequest.GetRequestStream()
            oStream.Write(oRequestParametersByteArray, 0, oRequestParametersByteArray.Length)

            If Not oStream Is Nothing Then

                oWebResponse = oWebRequest.GetResponse()

            End If
        End If
    End If

    Return oWebResponse
End Function

Protected Function ReadWebResponse(ByVal oWebResponse As WebResponse) As String
    Dim sWebResponse As String = String.Empty

    Dim oStream As Stream
    Dim oStreamReader As StreamReader

    Try

        If IsNothing(oWebResponse) = False Then

            oStream = oWebResponse.GetResponseStream()

            If IsNothing(oStream) = False Then

                oStreamReader = New StreamReader(oStream)

                If Not oStreamReader Is Nothing Then

                    oStreamReader = New StreamReader(oStream)

                    If IsNothing(oStreamReader) = False Then

                        sWebResponse = oStreamReader.ReadToEnd()

                    End If

                End If

            End If

        End If

    Catch oException As Exception

    End Try

    Return sWebResponse
End Function

End Class

Got it to work. He is what the problem was, folks. I would generate the Authorization Code and would play with it for hours trying to see what I keep getting bad request.

The thing is (special thanks to Rich Sutton's Answer here) that once you does not seem to be able to get the Access Token / Refresh Token using the same Authorization Code after the initial time of doing that.

Here is your friend by the way - Google OAuth 2.0 Playground

Otherwords:

  1. You go generate the Authorization Code by putting together a URL passing ClientID, ClientSecret and Redirect URI (plus whatever parameters you want to pass)
  2. If you data is You Will Get Back An Authorization Code
Community
  • 1
  • 1
Alexey Shevelyov
  • 926
  • 1
  • 13
  • 24