1

我目前正在开始工作,Xamarin.Auth我面临着 2 个问题,自 1 天半以来我一直在解决这些问题。

我有这段代码:

public class OAuth
{
    private Account account;
    private AccountStore store;

    // These values do not need changing
    public string Scope;
    public string AuthorizeUrl;
    public string AccessTokenUrl;
    public string UserInfoUrl;

    string clientId;
    string redirectUri;

    private Func<JObject, User> OAuthParser;

    private Action<User> OnCompleted;
    private Action<string> OnError;

    public OAuth()
    {
        account = null;
        store = null;

        Scope = "";
        AuthorizeUrl = "";
        AccessTokenUrl = "";
        UserInfoUrl = "";

        clientId = "";
        redirectUri = "";
    }

    public OAuth Facebook()
    {
        // These values do not need changing
        Scope = "public_profile";
        AuthorizeUrl = "https://m.facebook.com/dialog/oauth/";
        AccessTokenUrl = "";
        UserInfoUrl = "";

        switch (Device.RuntimePlatform)
        {
            case Device.iOS:
                clientId = "<insert IOS client ID here>";
                redirectUri = "<insert IOS redirect URL here>:/oauth2redirect";
                break;

            case Device.Android:
                clientId = "206316176526191";
                redirectUri = "http://www.facebook.com/connect/login_success.html";
                break;
        }

        OAuthParser = ParseFacebookResponse;

        return this;
    }

    public OAuth GooglePlus()
    {
        // These values do not need changing
        Scope = "https://www.googleapis.com/auth/userinfo.email";
        AuthorizeUrl = "https://accounts.google.com/o/oauth2/auth";
        AccessTokenUrl = "https://www.googleapis.com/oauth2/v4/token";
        UserInfoUrl = "https://www.googleapis.com/oauth2/v2/userinfo";

        switch (Device.RuntimePlatform)
        {
            case Device.iOS:
                clientId = "<insert IOS client ID here>";
                redirectUri = "<insert IOS redirect URL here>:/oauth2redirect";
                break;

            case Device.Android:
                clientId = "548539660999-muighch5brcrbae8r53js0ggdad5jt45.apps.googleusercontent.com";
                redirectUri = "com.googleusercontent.apps.548539660999-muighch5brcrbae8r53js0ggdad5jt45:/oauth2redirect";
                break;
        }

        OAuthParser = ParseGooglePlusResponse;

        return this;
    }

    public OAuth2Authenticator Authenticator(Action<User> onCompleted, Action<string> onError)
    {
        OAuth2Authenticator authenticator = new OAuth2Authenticator(
            clientId,
            null,
            Scope,
            new Uri(AuthorizeUrl),
            new Uri(redirectUri),
            new Uri(AccessTokenUrl),
            null,
            false);

    authenticator.Completed += OnAuthCompleted;
    authenticator.Error += OnAuthError;

        OnCompleted = onCompleted;
        OnError = onError;

        return authenticator;
    }

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

    //User user = null;
    if (e.IsAuthenticated)
    {
        // If the user is authenticated, request their basic user data from Google
        // UserInfoUrl = https://www.googleapis.com/oauth2/v2/userinfo
        var request = new OAuth2Request("GET", new Uri(UserInfoUrl), null, e.Account);
        var response = await request.GetResponseAsync();
        if (response != null)
        {
                // Deserialize the data and store it in the account store
                // The users email address will be used to identify data in SimpleDB
                string str = await response.GetResponseTextAsync();
                JObject jobject = JObject.Parse(str);
                User user = OAuthParser(jobject);

                OnCompleted(user);
        }

        if (account != null)
        {
            store.Delete(account, App.AppName);
        }

        await store.SaveAsync(account = e.Account, App.AppName);
    }
}

private void OnAuthError(object sender, AuthenticatorErrorEventArgs e)
{
        OAuth2Authenticator OAuth2Authenticator = sender as OAuth2Authenticator;

    if (OAuth2Authenticator != null)
    {
        OAuth2Authenticator.Completed -= OnAuthCompleted;
        OAuth2Authenticator.Error -= OnAuthError;
    }

    OnError("Authentication error: " + e.Message);
}

    private static User ParseGooglePlusResponse(JObject jobject)
    {
        try
        {
            User user = new User()
            {
                Email = jobject["email"].ToString(),
                Pseudo = jobject["name"].ToString(),
                Firstname = jobject["given_name"].ToString(),
                Surname = jobject["family_name"].ToString(),
                Image = jobject["picture"].ToString(),
                Password = "girafe"
            };
            return user;
        }
        catch (Exception e) 
        { Debug.WriteLine(e.ToString()); }
        return null;
    }

    private static User ParseFacebookResponse(JObject jobject)
    {
        try
        {
            Debug.WriteLine(jobject);
            User user = new User()
            {
                Email = jobject["email"].ToString(),
                Pseudo = jobject["name"].ToString(),
                Firstname = jobject["given_name"].ToString(),
                Surname = jobject["family_name"].ToString(),
                Image = jobject["picture"].ToString(),
                Password = "girafe"
            };
            return user;
        }
        catch (Exception e)
        { Debug.WriteLine(e.ToString()); }
        return null;
    }
}

所以,我正在使用这个类:

private void FacebookAuthConnection()
    {
        AuthenticationState.Authenticator = OAuthService.Facebook().Authenticator(OAuthLoginCompleted, OAuthLoginError);
        Presenter.Login(AuthenticationState.Authenticator);
    }

但是,问题来了。首先,GooglePlus 可以工作,但是我在我的 android 手机上收到了一条警报,上面写着“Chrome 自定义选项卡不关闭 ...”,所以应用程序崩溃并显示一个空的堆栈跟踪...我在网上搜索,我唯一得到的就是将 的最后一个参数设置为 false new OAuth2Authenticator();,这不起作用,因为谷歌不允许从 webview...

所以我想,好的,我的代码有效,我得到了用户信息 blablabla,如果它在本机浏览器中有效,让我们尝试使用 facebook。但是,我找不到参数 URL...

Scope = "";
AuthorizeUrl = "";
AccessTokenUrl = "";
UserInfoUrl = "";
  • 范围似乎是public_profile
  • AuthorizationUrl将是https://m.facebook.com/dialog/oauth/

但是另外两个呢?我有它们用于 Google+。

我真的被困住了,我觉得,每一秒过去,我都会越来越沮丧……

感谢 !


编辑

我的实际值:

Scope = "email";
AuthorizeUrl = "https://www.facebook.com/v2.8/dialog/oauth";
AccessTokenUrl = "https://graph.facebook.com/oauth/access_token";
UserInfoUrl = "https://graph.facebook.com/me?fields=email,name,gender,picture\"";

clientId = "XXXX";
redirectUri = "http://www.facebook.com/connect/login_success.html";
4

1 回答 1

2

Facebook 允许在嵌入式 Web 视图中进行授权。因此,它所做的就是将外部身份验证(在 chrome 选项卡中)用于 google+(在某些设备上,它只是在授权后不会返回到我的应用程序)——就像你做的那样。但是对于 Facebook 和 VKontakte,我在 webviews 中使用了 xamarin.auth,它的问题要少得多,除了登录视图设计之外,您可以完全控制一切。除了在 UWP ofc 上,整个过程仍然有问题。

回答有关 webview 身份验证过程的 facebook 正确参数的问题:

// OAuth Facebook
// For Facebook login, configure at https://developers.facebook.com/apps
public static string FacebookClientId = "XXX";
public static string FacebookScope = "email";
public static string FacebookAuthorizeUrl = "https://www.facebook.com/v2.9/dialog/oauth";
public static string FacebookAccessTokenUrl = "https://graph.facebook.com/oauth/access_token";

用作:

auth = new OAuth2Authenticator(
                        clientId: Constants.FacebookClientId,  
                        scope: "email",
                        authorizeUrl: new Uri("https://www.facebook.com/v2.9/dialog/oauth"), // These values do not need changing
                        redirectUrl: new Uri("http://www.facebook.com/connect/login_success.html")// These values do not need changing
                    );

在您获得用户详细信息之后:

var request1 = new OAuth2Request("GET", new Uri("https://graph.facebook.com/me?fields=email,first_name,last_name,gender,picture"), null, eventArgs.Account);
于 2017-08-30T15:27:47.533 回答