适用于Android的Xamarin Google SignIn - 刷新和访问令牌

时间:2017-03-02 11:11:33

标签: android xamarin token google-signin

使用VisualStudio,我最近通过Xamarin.Forms包为我的Xamarin.Google.iOS.SignIn NuGet应用成功实施了客户端流认证。然后,此登录用于允许应用程序通过Azure移动服务MobileServicesClient访问我们的服务器API组件。

它取决于是否能够从Google IDP API向{Azure,access_tokenrefresh_tokenid_token传递给所有这些内容 - 所有这3个在登录后都可以很好地使用{ {1}},SignIn.SharedInstance.CurrentUser.Authentication.AccessTokenSignIn.SharedInstance.CurrentUser.Authentication.RefreshToken

我现在正尝试使用SignIn.SharedInstance.CurrentUser.Authentication.IdToken包在我们的Xamarin.Forms应用的Android版本中实现类似行为。 但是,虽然我认为我已经掌握了使用Google成功进行身份验证的基础知识,但我看不出如何从结果中检索我需要的令牌。

Google文档讨论了在构建APIClient之前通过设置Xamarin.GooglePlayServices.Auth NuGet对象来启用IDTokenServerAuthCode的检索,而不是如何获取GoogleSignInOptions或来自谷歌的refresh_?它似乎想把这个责任放在我们的服务器API上。这不是我们的iOS应用程序的工作方式。有没有人使用这个NuGet包API在应用程序中成功完成此操作? Xamarin Android Google SignIn API是否支持我想要做的事情?

1 个答案:

答案 0 :(得分:0)

是的,这是可能的,请尝试以下类似的操作(忽略App.PostLoginAction的位置-这是我的应用程序专用的,尽管您当然可以采取类似的方法并像我所做的那样在应用程序级别实施操作赶上结果)。

public class GoogleLoginService : Java.Lang.Object, GoogleApiClient.IConnectionCallbacks, GoogleApiClient.IOnConnectionFailedListener
{
    public static GoogleApiClient GoogleApiClient { get; set; }
    public static GoogleLoginService Instance { get; private set; }

    public GoogleLoginService()
    {
        Instance = this;
        GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DefaultSignIn)
            .RequestIdToken("YourAppsWebClientId") //note this is the WEB client id, NOT the android app client id
            .RequestEmail()
            .Build();

        GoogleApiClient = new GoogleApiClient.Builder(CrossCurrentActivity.Current.Activity) //note you need to install the plugin king's (James Montemagno) Plugin.CurrentActivity nuget for this
            .AddConnectionCallbacks(this)
            .AddOnConnectionFailedListener(this)
            .AddApi(Auth.GOOGLE_SIGN_IN_API, gso)
            .AddScope(new Scope(Scopes.Email))
            .AddScope(new Scope(Scopes.Profile))
            .Build();
    }

    public void Login()
    {
        Intent signInIntent = Auth.GoogleSignInApi.GetSignInIntent(GoogleApiClient);
        CrossCurrentActivity.Current.Activity.StartActivityForResult(signInIntent, 1);
        GoogleApiClient.Connect();
    }

    public void Logout()
    {
        GoogleApiClient.Disconnect();
    }

    public void OnAuthCompleted(GoogleSignInResult result)
    {
        if (result.IsSuccess)
        {               
            Task.Factory.StartNew(()=> {
                //note result.SignInAccount.IdToken is NOT the access token, so we need this:
                var accessToken = GoogleAuthUtil.GetToken(Android.App.Application.Context, result.SignInAccount.Account, $"oauth2:{Scopes.Email} {Scopes.Profile}");
                App.PostLoginAction(SocialProvider.Google, accessToken , "Success!");
            });

            //to get user profile directly, without having to make separate call using the access token:
            GoogleSignInAccount account = result.SignInAccount; //contains stuff like name, email, pic url, gender
        }
        else
        {
            App.PostLoginAction(SocialProvider.Google, null, "An error occurred.");
        }
    }

    public void OnConnected(Bundle connectionHint)
    {

    }

    public void OnConnectionSuspended(int cause)
    {
        App.PostLoginAction(SocialProvider.Google, null, "Canceled!");
    }

    public void OnConnectionFailed(ConnectionResult result)
    {
        App.PostLoginAction(SocialProvider.Google, null, $"An error occurred: {result.ErrorMessage}");
    }
}