我试图在我的通用应用程序中添加谷歌登录,对于Windows 8.1应用程序,这很容易做到,但在Windows Phone 8.1 WinRT应用程序的情况下,下面是我写的代码:
private String simpleKey = "YOUR_SIMPLE_API_KEY"; // Should keep this secret
private String clientID = "ffffff- n12s9sab94p3j3vp95sdl7hrm2lbfk3e.apps.googleusercontent.com";
private string CALLBACKuri = "writeprovidedcallbackuri";
private String clientSecret = "LYffff2Q6MbgH623i"; // Keep it secret!
private String callbackUrl = "urn:ietf:wg:oauth:2.0:oob";
private String scope = "https://www.googleapis.com/auth/plus.me https://www.googleapis.com/auth/userinfo.email";
public GooglePlusLoginPage()
{
this.InitializeComponent();
refreshToken = null;
code = null;
access_token = null;
renderArea = this;
Auth();
}
public void Auth()
{
Windows.Storage.ApplicationData.Current.LocalSettings.Values["code"] = "";
if (access_token == null)
{
if (refreshToken == null && code == null)
{
try
{
String GoogleURL = "https://accounts.google.com/o/oauth2/auth?client_id=" + Uri.EscapeDataString(clientID) + "&redirect_uri=" + Uri.EscapeDataString(callbackUrl) + "&response_type=code&scope=" + Uri.EscapeDataString(scope);
System.Uri StartUri = new Uri(GoogleURL);
// When using the desktop flow, the success code is displayed in the html title of this end uri
System.Uri EndUri = new Uri("https://accounts.google.com/o/oauth2/approval?");
WebAuthenticationBroker.AuthenticateAndContinue(StartUri, EndUri, null, WebAuthenticationOptions.None);
// await Task.Delay(2);
}
catch (Exception Error)
{
((GooglePlusLoginPage)renderArea).SendToLangingPage();
}
}
}
//codeToAcccesTok();
}
/// <summary>
/// Invoked when this page is about to be displayed in a Frame.
/// </summary>
/// <param name="e">Event data that describes how this page was reached. The Parameter
/// property is typically used to configure the page.</param>
protected override void OnNavigatedTo(NavigationEventArgs e)
{
string name = e.Parameter as string;
IsGplusLogin = true;
// When the navigation stack isn't restored navigate to the ScenarioList
}
private void OutputToken(String TokenUri)
{
string access_token = TokenUri;
}
public void ContinueWebAuthentication(WebAuthenticationBrokerContinuationEventArgs args)
{
WebAuthenticationResult result = args.WebAuthenticationResult;
if (result.ResponseStatus == WebAuthenticationStatus.Success)
{
string response = result.ResponseData.ToString();
code = response.Substring(response.IndexOf("=") + 1);
Windows.Storage.ApplicationData.Current.LocalSettings.Values["code"] = code;
// TODO: switch off button, enable writes, etc.
}
else if (result.ResponseStatus == WebAuthenticationStatus.ErrorHttp)
{
//TODO: handle WebAuthenticationResult.ResponseErrorDetail.ToString()
}
else
{
((GooglePlusLoginPage)renderArea).SendToLangingPage();
// This could be a response status of 400 / 401
// Could be really useful to print debugging information such as "Your applicationID is probably wrong"
//TODO: handle WebAuthenticationResult.ResponseStatus.ToString()
}
codeToAcccesTok();
}
interface IWebAuthenticationContinuable
{
/// <summary>
/// This method is invoked when the web authentication broker returns
/// with the authentication result
/// </summary>
/// <param name="args">Activated event args object that contains returned authentication token</param>
void ContinueWebAuthentication(WebAuthenticationBrokerContinuationEventArgs args);
}
private async void codeToAcccesTok()
{
string oauthUrl = "https://accounts.google.com/o/oauth2/token";
HttpClient theAuthClient = new HttpClient();
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, oauthUrl);
// default case, we have an authentication code, want a refresh/access token
string content = "code=" + code + "&" +
"client_id=" + clientID + "&" +
"client_secret=" + clientSecret + "&" +
"redirect_uri=" + callbackUrl + "&" +
"grant_type=authorization_code";
if (refreshToken != null)
{
content = "refresh_token=" + refreshToken + "&" +
"client_id=" + clientID + "&" +
"client_secret=" + clientSecret + "&" +
"grant_type=refresh_token";
}
request.Method = HttpMethod.Post;
request.Content = new StreamContent(new System.IO.MemoryStream(System.Text.Encoding.UTF8.GetBytes(content)));
request.Content.Headers.Add("Content-Type", "application/x-www-form-urlencoded");
try
{
HttpResponseMessage response = await theAuthClient.SendAsync(request);
parseAccessToken(response);
}
catch (HttpRequestException)
{
}
}
public async void parseAccessToken(HttpResponseMessage response)
{
string content = await response.Content.ReadAsStringAsync();
//content="{n "error" : "invalid_request",n "error_description" : "Missing required parameter: code"n}";
if (content != null)
{
string[] lines = content.Replace(""", "").Replace(" ", "").Replace(",", "").Split('n');
for (int i = 0; i < lines.Length; i++)
{
string[] paramSplit = lines[i].Split(':');
if (paramSplit[0].Equals("access_token"))
{
access_token = paramSplit[1];
}
if (paramSplit[0].Equals("refresh_token"))
{
refreshToken = paramSplit[1];
Windows.Storage.ApplicationData.Current.LocalSettings.Values["refreshToken"] = refreshToken;
}
}
//access_token="ya29.aAAvUHg-CW7c1RwAAACtigeHQm2CPFbwTG2zcJK-frpMUNqZkVRQL5q90mF_bA";
if (access_token != null)
{
getProfile();
}
else
{
((GooglePlusLoginPage)renderArea).SendToLangingPage();
// something is wrong, fix this
}
}
}
private async void ParseProfile(HttpResponseMessage response)
{
string content = await response.Content.ReadAsStringAsync();
if (content != null)
{
var serializer = new DataContractJsonSerializer(typeof(UserEmail));
UserInfo = serializer.ReadObject(new System.IO.MemoryStream(System.Text.Encoding.UTF8.GetBytes(content))) as UserEmail;
((GooglePlusLoginPage)renderArea).RenderUser();
WebView wb = new WebView();
var url = "http://accounts.google.com/Logout";
wb.Navigate(new Uri(url, UriKind.RelativeOrAbsolute));
}
}
public async void getProfile()
{
httpClient = new HttpClient();
var searchUrl = "https://www.googleapis.com/oauth2/v2/userinfo";
httpClient.DefaultRequestHeaders.Add("Authorization", "Bearer " + access_token);
try
{
HttpResponseMessage response = await httpClient.GetAsync(searchUrl);
ParseProfile(response);
}
catch (HttpRequestException hre)
{
// DebugPrint(hre.Message);
}
}
public async void RenderUser()
{
GridProgressRing.Visibility = Visibility.Visible;
Imageuri = UserInfo.picture.ToString().Replace("sz=50", "sz=150");
displayname = UserInfo.name;
Google_Id = UserInfo.id;
emailid = UserInfo.Email;
first_name = displayname;
uniqueName = Imageuri.ToString();
string Imagefile = "";
if (ShareMenuClass.CheckInternetConnection())
{
Imagefile = await ShareMenuClass.ToBase64String(Imageuri);
}
if (first_name.Contains(' '))
{
string[] dfdf = new string[2];
dfdf = first_name.Split(' ');
first_name = dfdf[0];
last_name = dfdf[1];
}
password = "google user";
string DataString = "<UserRegistration>" + "<FirstName>" + first_name + "</FirstName><LastName>" + last_name + "</LastName><Platform>Windows 8</Platform>" +
"<UUID>" + getDeviceId() + "</UUID><EmailId>" + emailid + "</EmailId><Password>" + password + "</Password><Photo>" + Imagefile +
"</Photo><OrganiztionName>" + organization_name + "</OrganiztionName><Location>indore</Location><AppId>2</AppId><querytype>register</querytype></UserRegistration>";
if (ShareMenuClass.CheckInternetConnection())
{
string Front = "<UserRegistration xmlns="www.XMLWebServiceSoapHeaderAuth.net"> <UserRegistrationXml>";
string Back = "</UserRegistrationXml></UserRegistration>";
DataString = DataString.Replace("<", "<");
DataString = DataString.Replace(">", ">");
DataString = Front + DataString + Back;
string RecivedString = await ShareMenuClass.CallWebService("UserRegistration", DataString);
bool flagtoFillDefaultProgress = true;
if (RecivedString.Contains("Email Id is already registered"))
{
flagtoFillDefaultProgress = false;
string SoapXml = "<getuserProgressInfo><EmailId>" + emailid + "</EmailId><AppId>2</AppId></getuserProgressInfo>";
Front = "<getuserProgress xmlns="www.XMLWebServiceSoapHeaderAuth.net"><getuserProgressInfoXml>";
Back = "</getuserProgressInfoXml></getuserProgress>";
SoapXml = SoapXml.Replace("<", "<");
SoapXml = SoapXml.Replace(">", ">");
SoapXml = Front + SoapXml + Back;
RecivedString = await ShareMenuClass.CallWebService("getuserProgress", SoapXml);
}
if (RecivedString.Contains("success"))
{
txtplswait.Text = "Configuring your account...";
RecivedXml.RecivedStringToObserCollection(RecivedString);
//if (flagtoFillDefaultProgress)
//{
await System.Threading.Tasks.Task.Delay(25);
await RecivedXml.FillMyHalfList();
//}
RecivedXml.SerializeRecivedRecivedollection();
ShareMenuClass.Google_Loging = true;
if (RecivedXml.WholeRecivedData[0].response == "success")
{
StorageFile storagefile = await ApplicationData.Current.LocalFolder.CreateFileAsync("IsGoogleUser.txt", CreationCollisionOption.ReplaceExisting);
RecivedXml.SerializeSignedUserInfo(RecivedXml.WholeRecivedData[0].Id);
Quizstatemodleobj.GetOverallQuizProgressForAllUserAndFillThisUserList(RecivedXml.WholeRecivedData[0].Id);
await System.Threading.Tasks.Task.Delay(25);
GridProgressRing.Visibility = Visibility.Collapsed;
Frame.Navigate(typeof(TrainingModulesPage));
}
}
else
{
MessageDialog msg1 = new MessageDialog("Somthing went wrong.Try again later!");
await msg1.ShowAsync();
Frame.Navigate(typeof(RegistrationPage));
}
}
else
{
MessageDialog msg1 = new MessageDialog("You are not connected to internet!");
await msg1.ShowAsync();
Frame.Navigate(typeof(RegistrationPage));
}
}
public Page renderArea { get; set; }
public string refreshToken { get; set; }
public string code { get; set; }
这里的ContinueWebAuthentication是在用户接受让应用程序获取配置文件信息后触发的,"code"的值不是想要的,在W8.1应用程序中,"code"的值是正确的,但这里不是。因此,我无法获得用户配置文件信息
我终于想通了。
- 将AuthenticateAndContinue方法的"StartUri"参数中的"redirect_uri"查询参数修改为
http://localhost
- 将"AuthenticateAndContinue"方法的CallbackURL(或"EndUri")参数也更改为等于
http://localhost
几个小时后,这是我的工作。我通过浏览代码找到了答案:http://code.msdn.microsoft.com/windowsapps/Authentication-using-bb28840e,特别是在身份验证中查看类"GoogleService.cs"。解决方案的共享项目。