我正在开发一个Asp.NET MVC5 App following this Google sample code. 我希望应用程序经过身份验证并由用户创建一个accessstoken(配置阶段),之后我需要能够使用刷新令牌调用Google APis(在我的情况下为
我希望应用程序经过身份验证并由用户创建一个accessstoken(配置阶段),之后我需要能够使用刷新令牌调用Google APis(在我的情况下为Directory API)(无需用户干预,如“离线”).
控制器:
public async Task<ActionResult> IndexAsync(CancellationToken cancellationToken) { var result = await new AuthorizationCodeMvcApp(this, new AppFlowMetadata()). AuthorizeAsync(cancellationToken); if (result.Credential != null) { var service = new Google.Apis.Admin.Directory.directory_v1.DirectoryService(new BaseClientService.Initializer { HttpClientInitializer = result.Credential, ApplicationName = "My Application" }); return View(); } else { return new RedirectResult(result.RedirectUri); } }
FlowMetadata实现. (我使用FiledataStore稍加修改(GoogleFileDataStore))
public class AppFlowMetadata : FlowMetadata { //Move to settings static readonly string clientId = "xxxccnvofsdfsfoj.apps.googleusercontent.com"; static readonly string clientsecret = "xxxxxxxxxxLvtC6Qbqpp4x_"; static readonly string datastore = "AdminSDK.Api.Auth.Store"; private static readonly IAuthorizationCodeFlow flow = new GoogleAuthorizationCodeFlow(new GoogleAuthorizationCodeFlow.Initializer { ClientSecrets = new ClientSecrets { ClientId = clientId, ClientSecret = clientsecret }, Scopes = new[] { DirectoryService.Scope.AdminDirectoryUser, DirectoryService.Scope.AdminDirectoryUserAliasReadonly }, DataStore = new GoogleFileDataStore(datastore) }); public override string GetUserId(Controller controller) { return ConfigHelper.UserID.ToString(); } public override IAuthorizationCodeFlow Flow { get { return flow; } } }
当我调用IndexAsync控制器时,由于用户没有先前的accessstoken,它会在用户登录Google帐户后创建一个新的.
这是一个示例访问,
{“access_token”:“ya29.5gBOszGO-oYJJt4YZfF6FeaZth1f69 _…..”,“token_type”:“Bearer”,“expires_in”:3600,“Issued”:“2014-12-24T16:02:32.014 05:30” }
问题1:为什么没有存储Refreshtoken?如何检索refreshtoken?
问题2:如果我获得了refreshtoken,我应该如何修改代码以创建新的访问令牌并调用API(当accesstoken过期时)?
[我提到了this question,但缺少刷新令牌没有正确答案.
问题1:为什么没有存储Refreshtoken?如何检索refreshtoken?
我必须在请求中将access_type设置为脱机(默认情况下是在线). as mentioned here
我必须为GoogleAuthorizationCodeFlow类编写自己的实现.感谢this post.
public class ForceOfflineGoogleAuthorizationCodeFlow : GoogleAuthorizationCodeFlow { public ForceOfflineGoogleAuthorizationCodeFlow(GoogleAuthorizationCodeFlow.Initializer initializer) : base(initializer) { } public override AuthorizationCodeRequestUrl CreateAuthorizationCodeRequest(string redirectUri) { return new GoogleAuthorizationCodeRequestUrl(new Uri(AuthorizationServerUrl)) { ClientId = ClientSecrets.ClientId, Scope = string.Join(" ", Scopes), RedirectUri = redirectUri, AccessType = "offline", ApprovalPrompt = "force" }; } };
问题2:..我应该修改代码来创建新的访问令牌并调用API吗?
//try to get results var result = await new AuthorizationCodeMvcApp(this, new AppFlowMetadata()). AuthorizeAsync(cancellationToken); //// This bit checks if the token is out of date, //// and refreshes the access token using the refresh token. if (result.Credential.Token.IsExpired(SystemClock.Default)) { Google.Apis.Auth.OAuth2.Responses.TokenResponse token = new Google.Apis.Auth.OAuth2.Responses.TokenResponse(); //If the token is expired recreate the token token = await result.Credential.Flow.RefreshTokenAsync(ConfigHelper.UserID.ToString(), result.Credential.Token.RefreshToken, CancellationToken.None); //Get the authorization details back result = await new AuthorizationCodeMvcApp(this, new AppFlowMetadata()).AuthorizeAsync(cancellationToken); }
这对我有用!希望这会有助于其他人……