How to renew the access token using the refresh token?

前端 未结 2 1817
别那么骄傲
别那么骄傲 2020-12-01 02:04

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

相关标签:
2条回答
  • 2020-12-01 03:02

    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. enter image description here

    And this one shows the Katana Debug Symbols being loaded. enter image description here

    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

    0 讨论(0)
  • 2020-12-01 03:03

    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

    0 讨论(0)
提交回复
热议问题