如何从 Xamarin Auth 获取访问令牌 - Google

How to get accesstoken from Xamarin Auth - Google

我正在尝试从 android 应用程序中的 0auth2 获取授权令牌。问题是一旦我签名,由于重定向 url,应用程序正在重新启动,但是一旦应用程序重新启动,我就没有从意图中获得任何授权令牌。

代码

var authenticator = new OAuth2Authenticator(ClientID, ClientSecret, Scope, new Uri("https://accounts.google.com/o/oauth2/auth"),
                new Uri("com.app.abcd:/oauthredirect"), new Uri("https://oauth2.googleapis.com/token"), null, true);
 authenticator.Completed += OnAuthCompleted;
                authenticator.Error += OnAuthError;
                var presenter = new Xamarin.Auth.Presenters.OAuthLoginPresenter();
                presenter.Login(authenticator);

 private async void OnAuthCompleted(object sender, AuthenticatorCompletedEventArgs e)
        {
            var authenticator = sender as OAuth2Authenticator;
            if (authenticator != null)
            {
                authenticator.Completed -= OnAuthCompleted;
                authenticator.Error -= OnAuthError;
            }

            IsAuthorized = e.IsAuthenticated;
            //User user = null;
            if (e.IsAuthenticated)
            {}
}

Android

[Activity(Label = "ABCD", MainLauncher = true, LaunchMode = LaunchMode.SingleTask, ConfigurationChanges = ConfigChanges.ScreenSize, ScreenOrientation = ScreenOrientation.Portrait)]
    [IntentFilter(new[] { Intent.ActionView },
              Categories = new[] { Intent.CategoryBrowsable, Intent.CategoryDefault },
        //DataScheme = "abcd",
         DataSchemes = new[] { "com.app.abcd" },
               DataPath = "/oauthredirect",
              AutoVerify = true)]

    public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity
    {

protected override void OnCreate(Bundle bundle)
        {
            base.SetTheme(Resource.Style.MainTheme);
                base.OnCreate(bundle);
                DependencyService.Register<ChromeCustomTabsBrowser>();
                CrossCurrentActivity.Current.Activity = this;

                TabLayoutResource = Resource.Layout.Tabbar;
                ToolbarResource = Resource.Layout.Toolbar;

                global::Xamarin.Forms.Forms.Init(this, bundle);
                LoadApplication(new App());
        }
protected override void OnNewIntent(Intent intent)
        {
            base.OnNewIntent(intent);
            //HandleNotificationIntent(intent);
        }

        protected override void OnRestart()
        {
            var intent = this.Intent;
            base.OnRestart();
        }
}

当我 运行 调用此代码并调用 presenter.Login(authenticator); 时,我可以看到 google 对用户进行身份验证并调用 OnNewIntent 并重新启动应用程序 OnAuthCompleted 从未被调用,我无法获得访问令牌。

这是从 0auth2 获取访问令牌的正确方法还是我遗漏了什么?谁能帮我解决这个问题。

我找到了解决方案。查看示例 here.

常用代码:

 private void Authenticate()
        {
            var authenticator = new OAuth2Authenticator(ClientID, ClientSecret, Scope, new Uri("https://accounts.google.com/o/oauth2/auth"),
                            new Uri("com.app.abcd:/oauthredirect"), new Uri("https://oauth2.googleapis.com/token"), null, true);
            authenticator.Completed += OnAuthCompleted;
            authenticator.Error += OnAuthError;
            var presenter = new Xamarin.Auth.Presenters.OAuthLoginPresenter();
            presenter.Login(authenticator);
        }

        private async void OnAuthCompleted(object sender, AuthenticatorCompletedEventArgs e)
        {
            var authenticator = sender as OAuth2Authenticator;
            if (authenticator != null)
            {
                authenticator.Completed -= OnAuthCompleted;
                authenticator.Error -= OnAuthError;
            }

            IsAuthorized = e.IsAuthenticated;
            //User user = null;
            if (e.IsAuthenticated)
            {
                var access_token = e.Account.Properties["access_token"];
                var expires_in = e.Account.Properties["expires_in"];
                var refresh_token = e.Account.Properties["refresh_token"];
            }
        }

ANDROID: 创建一个新的 activity:

[Activity(Label = "ActivityCustomUrlSchemeInterceptor", NoHistory = true, LaunchMode = LaunchMode.SingleTop)]
    [IntentFilter(
        new[] { Intent.ActionView },
        Categories = new[] { Intent.CategoryDefault, Intent.CategoryBrowsable },
        DataSchemes = new[] { "com.app.abcd" },
        DataPath = "/oauthredirect")]
    public class ActivityCustomUrlSchemeInterceptor : Activity
    {
        protected override void OnCreate(Bundle savedInstanceState)
        {
            base.OnCreate(savedInstanceState);
            global::Android.Net.Uri uri_android = Intent.Data;

            // Convert Android.Net.Url to Uri
            var uri = new Uri(uri_android.ToString());
            // Close browser 
            var intent = new Intent(this, typeof(MainActivity));
            //intent.SetFlags(ActivityFlags.ClearTop | ActivityFlags.SingleTop);
            StartActivity(intent);

            // Load redirectUrl page
            // if the code below isn't accessible, pass `authenticator`
            // created in the common code here which has `OnPageLoading(uri);` method 
           OAuthAuthenticatorHelper.AuthenticationState.OnPageLoading(uri);
            this.Finish();
        }
    }

iOS

OpenUrl 中添加几行来处理 url 重定向

public override bool OpenUrl(UIApplication application, NSUrl url, string sourceApplication, NSObject annotation)
        {
            // Convert iOS NSUrl to C#/netxf/BCL System.Uri - common API
            Uri uri_netfx = new Uri(url.AbsoluteString);

            // load redirect_url Page for parsing
            OAuthAuthenticatorHelper.AuthenticationState.OnPageLoading(uri_netfx);

            return true;
        }

在info.plist中添加包名的url方案:

<key>CFBundleURLSchemes</key>
            <array>
              <string>com.app.abcd</string>
            </array>