如何使用刷新令牌续订访问令牌?

我正在使用带有OWIN的 ASP.NET MVC 5

我做了很多研究,但没有找到如何使用刷新令牌续订访问令牌。

我的方案是:用户第一次访问我的应用时,他或她授予访问我读取API返回的刷新令牌的帐户的权限。 当用户返回我的应用程序时,我需要根据“刷新令牌”刷新访问令牌。

有人可以提供一些代码吗?

这是我到目前为止所取得的成就:

Startup.Auth.cs:

var googleOAuth2AuthenticationOptions = new GoogleOAuth2AuthenticationOptions { Caption = "Google+", ClientId = Parameters.Instance.Authentication.oAuth.GooglePlus.ClientId, ClientSecret = Parameters.Instance.Authentication.oAuth.GooglePlus.ClientSecret, CallbackPath = new PathString("/oauth-login-return"), Provider = new GoogleOAuth2AuthenticationProvider { OnAuthenticated = async context => { context.Identity.AddClaim(new Claim(ClaimTypes.Name, context.Identity.FindFirstValue(ClaimTypes.Name))); context.Identity.AddClaim(new Claim(ClaimTypes.Email, context.Identity.FindFirstValue(ClaimTypes.Email))); context.Identity.AddClaim(new Claim("picture", context.User.GetValue("picture").ToString())); context.Identity.AddClaim(new Claim("profile", context.User.GetValue("profile").ToString())); context.Identity.AddClaim( new Claim(Parameters.Instance.Authentication.oAuth.GooglePlus.AccessTokenClaimType, context.AccessToken)); } } }; googleOAuth2AuthenticationOptions.Scope.Add("https://www.googleapis.com/auth/plus.login"); googleOAuth2AuthenticationOptions.Scope.Add("https://www.googleapis.com/auth/userinfo.email"); 

AuthenticationController:

 [HttpPost] [AllowAnonymous] public ActionResult ExternalLogin(string provider, string returnUrl) { RedirectIfAuthenticated(); return new ChallengeResult(provider, Url.Content("~/oauth-login-callback")); } [ActionName("oauth-login-back")] public async Task ExternalLoginCallback(string returnUrl) { } // Used for XSRF protection when adding external logins private const string XsrfKey = "XsrfId"; private IAuthenticationManager AuthenticationManager { get { return HttpContext.GetOwinContext().Authentication; } } private class ChallengeResult : HttpUnauthorizedResult { public ChallengeResult(string provider, string redirectUri) : this(provider, redirectUri, null) { } private ChallengeResult(string provider, string redirectUri, string userId) { LoginProvider = provider; RedirectUri = redirectUri; UserId = userId; } private string LoginProvider { get; set; } private string RedirectUri { get; set; } private string UserId { get; set; } public override void ExecuteResult(ControllerContext context) { var properties = new AuthenticationProperties { RedirectUri = RedirectUri }; if (UserId != null) { properties.Dictionary[XsrfKey] = UserId; } context.HttpContext.GetOwinContext().Authentication.Challenge(properties, LoginProvider); } } 

这个问题并非重复。 我希望这能帮助别人不要像我花的那样度过几天。

差不多4天后,我发现了如何使用OWIN在google api中获取新的访问令牌。

我将发布解决方案,但首先,我必须说,帮助我开始弄清楚我的错误的是设置Katana项目的调试符号。 请参阅此链接: http : //www.symbolsource.org/Public/Home/VisualStudio

此图显示了如何配置调试符号服务器。 在此处输入图像描述

这一个显示正在加载的Katana调试符号。 在此处输入图像描述

之后,我发现我的问题是Google API正在返回403:Forbidden

“未配置访问权限。请使用Google Developers Console激活项目的API”

然后,发现堆栈溢出这篇文章: “访问未配置。请使用Google Developers Console激活项目的API。”

更具体地说,这个答案: https : //stackoverflow.com/a/24401189/833846

之后,我访问了Google Developers Console并设置了Google+ API

然后,voillá! 有效。

现在,使用刷新令牌获取新访问令牌的代码(我还没有找到任何方法来使用OWIN API实现这一点)。

 public static class TokenValidator { ///  /// Obtém um novo access token na API do google. ///  ///  ///  ///  ///  public static GoogleRefreshTokenModel ValidateGoogleToken(string clientId, string clientSecret, string refreshToken) { const string url = "https://accounts.google.com/o/oauth2/token"; var parameters = new List> { new KeyValuePair("client_id", clientId), new KeyValuePair("client_secret", clientSecret), new KeyValuePair("grant_type", "refresh_token"), new KeyValuePair("refresh_token", refreshToken) }; var content = GetContentAsync(url, "POST", parameters); var token = JsonConvert.DeserializeObject(content); return token; } private static string GetContentAsync(string url, string method = "POST", IEnumerable> parameters = null) { return method == "POST" ? PostAsync(url, parameters) : GetAsync(url, parameters); } private static string PostAsync(string url, IEnumerable> 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> 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> 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> 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; } } 

重要事项1:要获取刷新令牌,必须在“ ExecuteResult ”方法中将“access_type”设置为“offline”,这样:

 properties.Dictionary["access_type"] = "offline"; 

重要信息2:获得刷新令牌后,您必须将其存储在某个安全源中。 Google API不会向您发出新的刷新令牌,除非您在调用该行之前将“approval_prompt”设置为“强制”(使用相同的方法):

 context.HttpContext.GetOwinContext().Authentication.Challenge(properties, LoginProvider); 

我还建议你看看:

Google API离线版访问

Google OAUTH 2.0 Playground

Google API发现检查

花了最后两天搞清楚如何更新访问令牌。 答案发布在另一个post中:

Google API V 3.0 .Net库和Google OAuth2如何处理刷新令牌