[英]How to renew the access token using the refresh token?
I am using ASP.NET MVC 5 with OWIN . 我正在使用带有OWIN的 ASP.NET MVC 5 。
I have done a lot of research and haven't found how to renew the access token using the refresh token. 我做了很多研究,但没有找到如何使用刷新令牌续订访问令牌。
My scenario is: The first time the user accesses my app, he or she grants access to the account I read the refresh token returned from the API. 我的方案是:用户第一次访问我的应用时,他或她授予访问我读取API返回的刷新令牌的帐户的权限。 When the users come back to my app, I need to refresh the access token based on the "Refresh Token".
当用户返回我的应用程序时,我需要根据“刷新令牌”刷新访问令牌。
Could anybody provide some code? 有人可以提供一些代码吗?
Here is what I've achieved till now: 这是我到目前为止所取得的成就:
Startup.Auth.cs: 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: 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<ActionResult> 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);
}
}
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. 差不多4天后,我发现了如何使用OWIN在google api中获取新的访问令牌。
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. 我将发布解决方案,但首先,我必须说,帮助我开始弄清楚我的错误的是设置Katana项目的调试符号。 See this link: http://www.symbolsource.org/Public/Home/VisualStudio
请看以下链接: 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. 这一个显示正在加载的Katana调试符号。
After that, I found out that my problem was that Google API was returning 403: Forbidden 之后,我发现我的问题是Google API正在返回403:Forbidden
"Access Not Configured. Please use Google Developers Console to activate the API for your project" “未配置访问权限。请使用Google Developers Console激活项目的API”
Then, found on stack overflow this post: "Access Not Configured. Please use Google Developers Console to activate the API for your project." 然后,发现堆栈溢出这篇文章: “访问未配置。请使用Google Developers Console激活项目的API。”
more specifically this Answer: https://stackoverflow.com/a/24401189/833846 更具体地说,这个答案: https : //stackoverflow.com/a/24401189/833846
After that, I went to Google Developers Console and setup up Google+ API 之后,我访问了Google Developers Console并设置了Google+ API
And then, voillá! 然后,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). 现在,使用刷新令牌获取新访问令牌的代码(我还没有找到任何方法来使用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: 重要事项1:要获取刷新令牌,必须在“ ExecuteResult ”方法中将“access_type”设置为“offline”,这样:
properties.Dictionary["access_type"] = "offline";
IMPORTANT 2: Once you get your refresh token, you must store it and in some secure source. 重要信息2:获得刷新令牌后,您必须将其存储在某个安全源中。 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):
Google API不会向您发送新的刷新令牌,除非您在调用该行之前将“approval_prompt”设置为“强制”(使用相同的方法):
context.HttpContext.GetOwinContext().Authentication.Challenge(properties, LoginProvider);
I also recommend taking a look at: 我还建议你看看:
Google API Offline Access Google API离线版访问
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 Google API V 3.0 .Net库和Google OAuth2如何处理刷新令牌
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.