Sagar
Sagar

Reputation: 7605

How to get access token for google oauth?

I am using C# (ASP.NET). I want to use Google OAuth for accessing the user profile detail in my app. I successfully got the authorization code but having a problem in getting the access token. I prefer the Google tutorials. In tutorial, I read that I have to send the request and get the response from google. For that, I use System.Net.HttpWebRequest/HttpWebResponse (am I going in the right way). I have used this code...

byte[] buffer = Encoding.ASCII.GetBytes("?code=" + code + "&client_id=xxx&client_secret=xxx&redirect_uri=xxxx&grant_type=authorization_code");
HttpWebRequest req = (HttpWebRequest)WebRequest.Create("http://accounts.google.com");
req.Method = "POST";
req.ContentType = "application/x-www-form-urlencoded";
req.ContentLength = buffer.Length;

Stream strm = req.GetRequestStream();
strm.Write(buffer, 0, buffer.Length);
strm.Close();

HttpWebResponse resp = (HttpWebResponse)req.GetResponse();
Response.Write(((HttpWebResponse)resp).StatusDescription);

But, I got the error:

The remote server returned an error: (405) Method Not Allowed.

Update: Here variable code is authorization code.

Upvotes: 11

Views: 40806

Answers (6)

Dmitry Sikorsky
Dmitry Sikorsky

Reputation: 1511

It was surprisingly difficult to find the correct and simple way of getting access token by auth code. (Especially because it has taken some time for me and then even with the correct code I got “invalid_grant” error because my auth code expired while searching :) )

So here is the code:

GoogleAuthorizationCodeFlow flow = new GoogleAuthorizationCodeFlow(
  new GoogleAuthorizationCodeFlow.Initializer
  {
    ClientSecrets = new ClientSecrets()
    {
      // Use ones from "Web SDK configuration" section if you created your app in Firebase.
      ClientId = "…",
      ClientSecret = "…"
    },
    Scopes = new[] { "email" },
  }
);

TokenResponse token = await  flow.ExchangeCodeForTokenAsync(string.Empty, "4/…", string.Empty, CancellationToken.None);

As you can see, userId can be just empty, as well as redirectUri. Don’t forget to add the Google.Apis.Auth Nuget package reference.

Upvotes: 0

Sahil Bhatia
Sahil Bhatia

Reputation: 175

public string ReceiveTokenGmail(string code, string GoogleWebAppClientID, string GoogleWebAppClientSecret, string RedirectUrl)
{
    string postString = "code=" + code + "&client_id=" + GoogleWebAppClientID + @"&client_secret=" + GoogleWebAppClientSecret  + "&redirect_uri=" + RedirectUrl;

    string url = "https://accounts.google.com/o/oauth2/token";

    HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url.ToString());
    request.Method = "POST";
    request.ContentType = "application/x-www-form-urlencoded";

    UTF8Encoding utfenc = new UTF8Encoding();
    byte[] bytes = utfenc.GetBytes(postString);
    Stream os = null;
    try
    {
        request.ContentLength = bytes.Length;
        os = request.GetRequestStream();
        os.Write(bytes, 0, bytes.Length);
    }
    catch
    { }
    string result = "";

    HttpWebResponse webResponse = (HttpWebResponse)request.GetResponse();
    Stream responseStream = webResponse.GetResponseStream();
    StreamReader responseStreamReader = new StreamReader(responseStream);
    result = responseStreamReader.ReadToEnd();

    return result;
}

Upvotes: 0

Neno
Neno

Reputation: 767

As I had similar problems in the process of implementing Google auth, I will post the code that works.. The last mentioned problem: error (400) Bad request could be caused by leading '?' in the above code..

 string codeClient = "code="+ t +"&client_id=number.apps.googleusercontent.com&";
 string secretUri = "client_secret=yoursecret&" + "redirect_uri=path&"
      + "grant_type=authorization_code";
 postString = codeClient + secretUri;

 string url = "https://accounts.google.com/o/oauth2/token";

 HttpWebRequest request = (HttpWebRequest) WebRequest.Create(url.ToString());
 request.Method = "POST";
 request.ContentType = "application/x-www-form-urlencoded";

 UTF8Encoding utfenc = new UTF8Encoding();
 byte[] bytes = utfenc.GetBytes(postString);
 Stream os = null;
 try
 {
      request.ContentLength = bytes.Length;
      os = request.GetRequestStream();
      os.Write(bytes, 0, bytes.Length);
 }
 catch
 { }

 try
 {
      HttpWebResponse webResponse = (HttpWebResponse) request.GetResponse();
      Stream responseStream = webResponse.GetResponseStream();
      StreamReader responseStreamReader = new StreamReader(responseStream);
      result = responseStreamReader.ReadToEnd();//parse token from result

Upvotes: 4

Sunny Jim
Sunny Jim

Reputation: 605

The original request seems to be somewhat outdated. But I found that the Google's code examples contain lots of "Best Practices" housekeeping code that's hard to separate from the essential operations.

I recently published a document that represents all the REST operations as curl commands. It's hard to be conversant in every language, but curl seems universal. Most people know it- otherwise, it's pretty easy to grasp. In my curl examples, the -d flag indicates a POST operation. Otherwise, the parameters are appended to the URL.

http://www.tqis.com/eloquency/googlecalendar.htm

Upvotes: 0

Sagar
Sagar

Reputation: 7605

My code is working, I have done mistakes in above two lines. It should be like this

byte[] buffer = Encoding.ASCII.GetBytes("code=" + code + "&client_id=xxx&client_secret=xxx&redirect_uri=xxxx&grant_type=authorization_code");
HttpWebRequest req = (HttpWebRequest)WebRequest.Create("https://accounts.google.com/o/oauth2/token");

Remaining code is correct.

Upvotes: 2

Claudio Cherubino
Claudio Cherubino

Reputation: 15024

I think you are sending the POST request to the wrong endpoint, the correct one is https://accounts.google.com/o/oauth2/token

Upvotes: 10

Related Questions