I am using ASP.NET MVC 5 with OWIN.
I have done a lot of research and haven\'t found how to renew the access token using the refres
This question isn't duplicate AT ALL. I hope this help others not spending days like I have spent.
After almost 4 days I have found out how to get a fresh access token in the google api using OWIN.
I'm going to post the solution, but first, I MUST say that what helped me to start getting a clue about my error was setting up the Debug Symbols for the Katana project. See this link: http://www.symbolsource.org/Public/Home/VisualStudio
This image show how to configure Debug Symbols Servers.
And this one shows the Katana Debug Symbols being loaded.
After that, I found out that my problem was that Google API was returning 403: Forbidden
"Access Not Configured. Please use Google Developers Console to activate the API for your project"
Then, found on stack overflow this post: "Access Not Configured. Please use Google Developers Console to activate the API for your project."
more specifically this Answer: https://stackoverflow.com/a/24401189/833846
After that, I went to Google Developers Console and setup up Google+ API
And then, voillá! It worked.
Now, the code to get a fresh access token using the refresh token (I haven't found any way to accomplish that using the OWIN API).
public static class TokenValidator
{
/// <summary>
/// Obtém um novo access token na API do google.
/// </summary>
/// <param name="clientId"></param>
/// <param name="clientSecret"></param>
/// <param name="refreshToken"></param>
/// <returns></returns>
public static GoogleRefreshTokenModel ValidateGoogleToken(string clientId, string clientSecret, string refreshToken)
{
const string url = "https://accounts.google.com/o/oauth2/token";
var parameters = new List<KeyValuePair<string, string>>
{
new KeyValuePair<string, string>("client_id", clientId),
new KeyValuePair<string, string>("client_secret", clientSecret),
new KeyValuePair<string, string>("grant_type", "refresh_token"),
new KeyValuePair<string, string>("refresh_token", refreshToken)
};
var content = GetContentAsync(url, "POST", parameters);
var token = JsonConvert.DeserializeObject<GoogleRefreshTokenModel>(content);
return token;
}
private static string GetContentAsync(string url,
string method = "POST",
IEnumerable<KeyValuePair<string, string>> parameters = null)
{
return method == "POST" ? PostAsync(url, parameters) : GetAsync(url, parameters);
}
private static string PostAsync(string url, IEnumerable<KeyValuePair<string, string>> parameters = null)
{
var uri = new Uri(url);
var request = WebRequest.Create(uri) as HttpWebRequest;
request.Method = "POST";
request.KeepAlive = true;
request.ContentType = "application/x-www-form-urlencoded";
var postParameters = GetPostParameters(parameters);
var bs = Encoding.UTF8.GetBytes(postParameters);
using (var reqStream = request.GetRequestStream())
{
reqStream.Write(bs, 0, bs.Length);
}
using (var response = request.GetResponse())
{
var sr = new StreamReader(response.GetResponseStream());
var jsonResponse = sr.ReadToEnd();
sr.Close();
return jsonResponse;
}
}
private static string GetPostParameters(IEnumerable<KeyValuePair<string, string>> parameters = null)
{
var postParameters = string.Empty;
foreach (var parameter in parameters)
{
postParameters += string.Format("&{0}={1}", parameter.Key,
HttpUtility.HtmlEncode(parameter.Value));
}
postParameters = postParameters.Substring(1);
return postParameters;
}
private static string GetAsync(string url, IEnumerable<KeyValuePair<string, string>> parameters = null)
{
url += "?" + GetQueryStringParameters(parameters);
var forIdsWebRequest = WebRequest.Create(url);
using (var response = (HttpWebResponse)forIdsWebRequest.GetResponse())
{
using (var data = response.GetResponseStream())
using (var reader = new StreamReader(data))
{
var jsonResponse = reader.ReadToEnd();
return jsonResponse;
}
}
}
private static string GetQueryStringParameters(IEnumerable<KeyValuePair<string, string>> parameters = null)
{
var queryStringParameters = string.Empty;
foreach (var parameter in parameters)
{
queryStringParameters += string.Format("&{0}={1}", parameter.Key,
HttpUtility.HtmlEncode(parameter.Value));
}
queryStringParameters = queryStringParameters.Substring(1);
return queryStringParameters;
}
}
IMPORTANT 1: To get a refresh token you must set the "access_type" to "offline" in the "ExecuteResult" method, this way:
properties.Dictionary["access_type"] = "offline";
IMPORTANT 2: Once you get your refresh token, you must store it and in some secure source. Google API won't issue you a new refresh token, unless you set "approval_prompt" to "force" before you call the line (in the same method):
context.HttpContext.GetOwinContext().Authentication.Challenge(properties, LoginProvider);
I also recommend taking a look at:
Google API Offline Access
Google OAUTH 2.0 Playground
Google API Discovery Check
Spent the last two days figuring out how to renew the access token myself. The answer is posted in another thread here:
How Google API V 3.0 .Net library and Google OAuth2 Handling refresh token