相关疑难解决方法(0)

使用OAuth2为app*和*网站进行身份验证

我正在开发一个主要通过应用程序访问的网站,我想使用OAuth2进行用户注册和身份验证.由于它是Android应用程序,我将开始使用Google的OAuth2内容,因为它在Android上提供了不错的用户界面.

Google表示,"您可以选择使用Google的身份验证系统作为外包用户身份验证的方式.这可以消除创建,维护和保护用户名和密码存储的需要." 这就是我想要做的.然而,当我浏览他们的所有示例和诸如此类的东西时,我只能找到有关网站应用程序根据Google服务对用户进行身份验证的内容.

事实上,当我使用Google的OAuth2注册我的应用程序("客户端")时,网站客户端和"已安装"客户端(即移动应用程序)可以选择,但不能同时选择两者.我可以创建两个单独的客户端,但我读了OAuth2草案,我认为会有一个问题,我现在将解释.

以下是我设想的工作方式:

OAuth2流程图

  1. 用户要求MyApp访问他的私人数据.
  2. 应用程序使用Android的AccountManager类为Google的API请求访问令牌.
  3. Android向用户说"应用'MyApp'希望在Google上访问您的基本信息.这可以吗?"
  4. 用户说是的.
  5. AccountManager 使用手机上存储的凭据连接到Google的OAuth2服务器,并要求提供访问令牌.
  6. 返回访问令牌(在绿线后面).
  7. AccountManager 将访问令牌返回给MyApp.
  8. MyApp向MySite发送请求以获取用户的私有数据,包括访问令牌.
  9. MySite需要使用访问令牌验证用户.它验证了此处描述的令牌,谷歌 - "谷歌,这个令牌有效吗?".
  10. 现在,我想要发生的事情是谷歌说"是的,无论是谁给你的确是那个用户."但我认为实际发生的事情(基于OAuth2草案和Google的文档)是它会说"不"方式!该令牌仅对MyApp有效,而且你是MySite.GTFO!".

那我该怎么做呢?请不要说"使用OpenID"或"不要使用OAuth2"或其他类似无益的答案.哦,我真的想用漂亮的,以保持AccountManager用户界面,而不是糟糕的弹出WebView小号

编辑

来自Nikolay的临时答案(我会报告它是否有效!)它实际上应该有效,而Google的服务器并不关心访问令牌的来源.对我来说似乎有点不安全,但我会看看它是否有效!

更新

我用Facebook而不是Google实现了这种模式,它完全有效.OAuth2服务器不关心访问令牌的来源.至少Facebook没有,所以我认为谷歌也没有.

鉴于此,存储访问令牌是一个非常糟糕的主意!但是我们也不想让Facebook/Google的服务器检查每个请求的身份验证,因为它会减慢一切.可能最好的办法是为您的站点添加一个额外的身份验证cookie,当您的访问令牌被验证时,您可以将其分发,但更简单的方法就是将访问令牌视为密码并存储其哈希值.你不需要加盐它,因为访问令牌真的很长.所以上面的步骤变成了:

9. MySite需要使用访问令牌验证用户.首先,它检查哈希有效访问令牌的缓存.如果在那里找到令牌的散列,则它知道用户已经过身份验证.否则,它会按照此处所述与Google进行核对- Google,"此令牌是否有效?".

10.如果Google说访问令牌无效,我们会告诉用户GTFO.否则谷歌说"是的,这是一个有效的用户",然后我们检查我们的注册用户数据库.如果找不到Google用户名(或Facebook id,如果使用Facebook),我们可以创建新用户.然后我们缓存访问令牌的散列值.

android oauth google-authentication oauth-2.0

63
推荐指数
2
解决办法
2万
查看次数

访问Google API - GoogleAccountCredential.usingOAuth2与GoogleAuthUtil.getToken()

最近,我一直在使用Android上的Google API,特别是Google Analytics,AdSense和Tasks API.

我见过Google提供的一些示例,他们使用此语句获取GoogleAccountCredential对象

https://code.google.com/p/google-api-java-client/source/browse/tasks-android-sample/src/main/java/com/google/api/services/samples/tasks/android/ TasksSample.java?repo=samples

credential = GoogleAccountCredential.usingOAuth2(this, Collections.singleton(TasksScopes.TASKS));

但是,如果我查看以下文档:
http://developer.android.com/google/auth/http-auth.html
http://developer.android.com/google/play-services/auth.html

他们都提到了下面用于获取令牌的方法:
token = GoogleAuthUtil.getToken(mActivity, mEmail, mScope);

我很困惑在哪种场景中使用哪一个以及为什么.我一直在使用Method no.1成功而无需在首选项中保留令牌(我猜这是由GoogleAccountCredential自动完成的)

  1. 任何人都可以告诉我为什么有人会使用第一种方法而不是第二种方法?

  2. 如何在第一种方法中访问身份验证令牌?

android google-api oauth-2.0 google-api-java-client

38
推荐指数
2
解决办法
2万
查看次数

来自Android客户端的AccountManager的AuthToken不再工作

我很生气.我正在尝试使用Java中的Google App Engine作为服务器,为Android构建一个基于回合制的多人在线游戏.

它们看起来非常合适.Android需要一个Google帐户,GAE使用Google帐户进行身份验证,同时具有免费和可扩展性.

因此,在假期之前,我可以使用Android 2.0中的新AccountManager API从我的Android客户端获取我的GAE应用程序的身份验证.以下代码允许您访问用户Google帐户的AuthToken,然后将其用于身份验证,以便用户无需手动输入其帐户用户名和密码:

   AccountManager mgr = AccountManager.get(this); 
   Account[] accts = mgr.getAccountsByType("com.google"); 
   Account acct = accts[0];
   AccountManagerFuture<Bundle> accountManagerFuture = mgr.getAuthToken(acct, "ah", null, this, null, null);
   Bundle authTokenBundle = accountManagerFuture.getResult(); 
   String authToken = authTokenBundle.get(AccountManager.KEY_AUTHTOKEN).toString();
Run Code Online (Sandbox Code Playgroud)

然后我能够将生成的AuthToken字符串附加到适当的URL并获得一个有效的cookie,然后我可以将其用于所有进一步的请求.唯一的问题是,上周的某个时候它刚刚停止为我工作.现在当我尝试使用上面代码中的AuthToken时,我没有返回cookie并且我的代码为丢失的cookie抛出了NullPointerException.

当我回到过去的方式时,当用户手动输入他们的Google用户名和密码并且我从" https://www.google.com/accounts/ClientLogin " 获得AuthToken时,它运行正常.

请告诉我有人使用用户手机上的Google帐户使用AuthToken为Google App Engine应用构建了一个Android客户端,并告诉我一些为什么不再有效的线索.

我真的很想做这个工作.我的替代方案是要求用户输入他们的凭证(这是笨重的,他们不应该做的),或者与服务器的另一个解决方案一起使用.

提前致谢.

authentication google-app-engine android accountmanager

36
推荐指数
1
解决办法
2万
查看次数

Android上使用OAuth2.0的Youtube Data API

我正在尝试在Android上使用带有OAuth 2.0身份验证的YouTubeData API,我正在努力解决这个问题.

我在网上搜索了很多,但对Android实现没什么帮助.

首先,我不清楚获得OAuth令牌的最佳方式是什么.在文档中,他们建议Android使用Google Play服务库获取它更好.真的吗?如果是,则按照本指南进行操作应该非常简单:https://developers.google.com/android/guides/http-auth.但此时我将在String对象中使用令牌..我应该如何在YouTubeData API中使用它?我应该把它放在某个地方YouTube.Builder吗?

YouTube youtube = new YouTube.Builder(Auth.HTTP_TRANSPORT, Auth.JSON_FACTORY, new HttpRequestInitializer() {
        public void initialize(HttpRequest request) throws IOException {
        }
    }).setApplicationName("AppName").build();
Run Code Online (Sandbox Code Playgroud)

如果有,有谁知道在哪里?

在StackOverflow上搜索我遇到了这个问题:获取Auth Token后的操作 - Android Youtube API.Ibrahim Ulukaya说这里使用起来更好 GoogleAccountCredential.根据我的理解(访问Google API - GoogleAccountCredential.usingOAuth2与GoogleAuthUtil.getToken()),Android版本GoogleAccountCredential应该使用GoogleAuthUtilGoogle Play服务库提供的内容,因此简化流程非常有用.我看过Ibrahim Ulukaya建议的示例项目(https://github.com/youtube/yt-direct-lite-android),我已经像他一样实现了一切.但它似乎不能很好地工作,因为我只在logcat中获取此消息:"存在IO错误:com.google.android.gms.auth.UserRecoverableAuthException:NeedPermission:null".
(请注意,我已在Google控制台上启用了所有必需的API,并为我的应用创建了客户端ID)

在这一点上,我有点迷茫.
我应该直接使用GoogleAuthUtilGoogle Play服务库吗?在这种情况下,一旦获得令牌,String我如何将其与YouTubeData API一起使用?
或者我应该使用GoogleAccountCredential?在这种情况下,有人知道如何解决"NeedPersmission:null"错误?

----编辑:

关于我的应用程序尝试做什么的详细信息: 这是我第一次使用这种API的经历,我从简单的东西开始:检索视频信息,然后播放这些视频,无需任何用户身份验证.我设法很容易做到这一点,但为了我的应用程序的目的,我需要访问用户数据,特别是用户必须能够喜欢和评论视频.所以我开始实现OAuth2,尝试执行我之前所做的相同的查询(检索视频信息).

android youtube-api oauth-2.0 google-play-services youtube-data-api

28
推荐指数
1
解决办法
6029
查看次数

AccountManagerFuture.getResult()导致"无法登录"屏幕

我正在尝试使用AccountManager获取已安装的Google帐户的令牌.当我在我的AccountManagerFuture对象上调用getResult()时,我在设备上看到"无法登录"屏幕(进一步说,"有一个探测器与Google服务器通信.稍后再试.".我检查了一下在调用此方法之前,网络连接可用.我还在浏览器中检查了我能够访问的设备,例如google.com.这是我的AccountManagerCallback的代码:

amf = accMgr.getAuthToken(account, authTokenType, null, true,  
    new AccountManagerCallback<Bundle>() {  
        public void run(AccountManagerFuture<Bundle> arg0) {  
            Bundle result;  
            Intent i;  
            String token;  

                try {        
                    result = arg0.getResult();  
                if (result.containsKey(AccountManager.KEY_INTENT)) {  
                     i = (Intent)result.get(AccountManager.KEY_INTENT);  
                     if (i.toString().contains("GrantCredentialsPermissionActivity")) {  
                         // Will have to wait for the user to accept  
                         // the request therefore this will have to  
                         // run in a foreground application  
                         cbt.startActivity(i);  
                     } else {  
                         cbt.startActivity(i);  
                     }

                     token = (String)result.get(AccountManager.KEY_AUTHTOKEN);  

                     } else {  
                         token = (String)result.get(AccountManager.KEY_AUTHTOKEN);       

                     }  
                 } catch (OperationCanceledException e) { …
Run Code Online (Sandbox Code Playgroud)

java android accountmanager

8
推荐指数
1
解决办法
1598
查看次数

虽然明确要求,但无法通过Google Plus帐户获得私人生日

我正在尝试从其Google Plus帐户中获取用户的信息,包括性别和年龄.由于这些字段可能是私有的,我认为明确请求它们可以解决问题.但是,尽管登录对话框明确指出应用程序请求View your complete date of birth,但我未能获得生日.

这些是我的范围(尝试了很多变化):

GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
        //.requestScopes(new Scope(Scopes.PROFILE))
        //.requestScopes(new Scope(Scopes.PLUS_LOGIN))
        .requestScopes(new Scope("https://www.googleapis.com/auth/user.birthday.read"),
                new Scope("https://www.googleapis.com/auth/userinfo.profile"))
        //.requestProfile()
        .requestEmail()
        .build();

mGoogleApiClient = new GoogleApiClient.Builder(this)
        .enableAutoManage(this, this)
        .addApi(Auth.GOOGLE_SIGN_IN_API, gso)
        .addApi(Plus.API)
        .addScope(new Scope(Scopes.PROFILE))
        .build();
Run Code Online (Sandbox Code Playgroud)

使用不推荐使用的getCurrentPersononActivityResult,我得到null值:

if (requestCode == RC_SIGN_IN) {
    GoogleSignInResult result = Auth.GoogleSignInApi.getSignInResultFromIntent(data);

    if (mGoogleApiClient.hasConnectedApi(Plus.API)) {
        Person person  = Plus.PeopleApi.getCurrentPerson(mGoogleApiClient);
        if (person != null) {
            Log.i(TAG, person.getDisplayName());    //returns full name successfully
            Log.i(TAG, person.getGender());         //0
            Log.i(TAG, person.getBirthday());       //null
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我也尝试从帐户( …

android google-plus google-play-services google-plus-signin google-signin

5
推荐指数
1
解决办法
3022
查看次数

Google Drive SDK例外

我正在尝试运行以下代码(主要来自Stephen Wylie):

package com.googledrive.googledriveapp;
// For Google Drive / Play Services
// Version 1.1 - Added new comments & removed dead code
// Stephen Wylie - 10/20/2012
import java.io.IOException;
import java.util.ArrayList;

import android.accounts.Account;
import android.accounts.AccountManager;
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;

import com.google.android.gms.auth.GoogleAuthException;
import com.google.android.gms.auth.GoogleAuthUtil;
import com.google.android.gms.auth.UserRecoverableAuthException;
import com.google.android.gms.common.AccountPicker;
import com.google.api.client.auth.oauth2.BearerToken;
import com.google.api.client.auth.oauth2.Credential;
import com.google.api.client.extensions.android2.AndroidHttp;
import com.google.api.client.googleapis.extensions.android2.auth.GoogleAccountManager;
import com.google.api.client.http.HttpRequestFactory;
import com.google.api.client.http.HttpTransport;
import …
Run Code Online (Sandbox Code Playgroud)

java android google-api google-drive-api

3
推荐指数
1
解决办法
7939
查看次数