Xamarin 身份验证 - Facebook 和 GooglePlus
Xamarin Auth - Facebook & GooglePlus
我目前正在开始使用 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;
}
}
所以,我正在这样使用 class:
private void FacebookAuthConnection()
{
AuthenticationState.Authenticator = OAuthService.Facebook().Authenticator(OAuthLoginCompleted, OAuthLoginError);
Presenter.Login(AuthenticationState.Authenticator);
}
但是,问题来了。首先,GooglePlus 可以工作,但是我在 android phone 上收到一条警告,上面写着 "Chrome Custom Tabs Doesn't Close ...",所以应用程序崩溃,堆栈跟踪为空...我在网上搜索,唯一得到的是将 new OAuth2Authenticator();
的最后一个参数变为 false,这不起作用因为 google 不允许从网络视图...
所以我想,好的,我的代码可以工作,我得到了用户信息 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";
Facebook 允许在嵌入式 Web 视图中进行授权。
因此,它所做的是对 google+ 使用外部身份验证(在 chrome 选项卡中)(在某些设备上,授权后它不会 return 到我的应用程序) - 就像你所做的那样。
但是对于 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);
我目前正在开始使用 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;
}
}
所以,我正在这样使用 class:
private void FacebookAuthConnection()
{
AuthenticationState.Authenticator = OAuthService.Facebook().Authenticator(OAuthLoginCompleted, OAuthLoginError);
Presenter.Login(AuthenticationState.Authenticator);
}
但是,问题来了。首先,GooglePlus 可以工作,但是我在 android phone 上收到一条警告,上面写着 "Chrome Custom Tabs Doesn't Close ...",所以应用程序崩溃,堆栈跟踪为空...我在网上搜索,唯一得到的是将 new OAuth2Authenticator();
的最后一个参数变为 false,这不起作用因为 google 不允许从网络视图...
所以我想,好的,我的代码可以工作,我得到了用户信息 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";
Facebook 允许在嵌入式 Web 视图中进行授权。 因此,它所做的是对 google+ 使用外部身份验证(在 chrome 选项卡中)(在某些设备上,授权后它不会 return 到我的应用程序) - 就像你所做的那样。 但是对于 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);