加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > asp.Net > 正文

asp.net-mvc – OAuth 2 Google API刷新令牌为空

发布时间:2020-12-16 09:12:12 所属栏目:asp.Net 来源:网络整理
导读:我正在开发一个Asp.NET MVC5 App following this Google sample code. 我希望应用程序经过身份验证并由用户创建一个accessstoken(配置阶段),之后我需要能够使用刷新令牌调用Google APis(在我的情况下为Directory API)(无需用户干预,如“离线”). 控制器: pu
我正在开发一个Asp.NET MVC5 App following this Google sample code.

我希望应用程序经过身份验证并由用户创建一个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,但缺少刷新令牌没有正确答案.

解决方法

找到了Google API离线访问的解决方案,以获取刷新令牌并使用刷新令牌创建新的accessstoken,

问题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);
     }

这对我有用!希望这会有助于其他人……

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读