所以,我正在开发应用程序的Android端,我需要让用户与他/她的Google联系人共享图像。为此,我显然需要用户的授权才能访问他或她的Google联系人。我们实现这一目标的方式如下:
所以,我只是按照Google的OAuth安排规定的流程进行操作。首先,我要求API授权授权代码。接下来,我发送此代码以获取访问令牌,然后最终将此访问令牌发送到我的服务器以通过Contacts API进行调用。
我向用户请求授权时获得的请求访问屏幕是:
最后,Contacts API发送了以下请求(示例请求来自许多):
但回复的回复是401.为什么它不是未经身份验证的,我不明白。我调试了几个小时,检查OAuth进程是否完全正常。
还有一件事,我使用以下范围登录Google:
GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
.requestServerAuthCode(CLIENT_ID, true)
.requestScopes(new Scope(Scopes.DRIVE_APPFOLDER), new Scope(Scopes.PROFILE))
.requestEmail()
.requestProfile()
.requestIdToken(CLIENT_ID)
.build();
有人可能会遇到什么问题吗?
修改
我提供了一些详细信息,证明API密钥,OAuth ID等的设置已经正确完成。
答案 0 :(得分:1)
正如我所怀疑的那样,Scope
证明是一个问题。
首先,让我告诉你,我一般都喜欢谷歌的精彩文档和API,但有些情况下,看似简单的细节被视为理所当然,开发人员感觉自己正在自己调试它们。我觉得,这是其中一个问题。
因此,任何启动Google登录集成的人都会查看官方文档和指南, 在文档中提及和使用范围,但是这样:
GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
.requestServerAuthCode(CLIENT_ID, true)
.requestScopes(new Scope(Scopes.DRIVE_APPFOLDER), new Scope(Scopes.PROFILE), new Scope(Scopes.EMAIL))
.requestEmail()
.requestProfile()
.requestIdToken(CLIENT_ID)
.build();
这是来自示例代码段。当然,开发人员从示例代码段中复制并进一步扩展它。那么,作为开发人员,我将如何扩展呢?
嗯,首先,我可以清楚地传递更多的范围吗?
这是对的,我做了那件事,但仍然遇到了这个问题。毕竟,我所要做的只是添加适当的范围。怎么会有人被这样打击?让我告诉你Scopes
类是什么样的:
public final class Scopes {
public static final java.lang.String PROFILE = "profile";
public static final java.lang.String EMAIL = "email";
public static final java.lang.String PLUS_LOGIN = "https://www.googleapis.com/auth/plus.login";
public static final java.lang.String PLUS_ME = "https://www.googleapis.com/auth/plus.me";
public static final java.lang.String GAMES = "https://www.googleapis.com/auth/games";
public static final java.lang.String CLOUD_SAVE = "https://www.googleapis.com/auth/datastoremobile";
public static final java.lang.String APP_STATE = "https://www.googleapis.com/auth/appstate";
public static final java.lang.String DRIVE_FILE = "https://www.googleapis.com/auth/drive.file";
public static final java.lang.String DRIVE_APPFOLDER = "https://www.googleapis.com/auth/drive.appdata";
public static final java.lang.String FITNESS_ACTIVITY_READ = "https://www.googleapis.com/auth/fitness.activity.read";
public static final java.lang.String FITNESS_ACTIVITY_READ_WRITE = "https://www.googleapis.com/auth/fitness.activity.write";
public static final java.lang.String FITNESS_LOCATION_READ = "https://www.googleapis.com/auth/fitness.location.read";
public static final java.lang.String FITNESS_LOCATION_READ_WRITE = "https://www.googleapis.com/auth/fitness.location.write";
public static final java.lang.String FITNESS_BODY_READ = "https://www.googleapis.com/auth/fitness.body.read";
public static final java.lang.String FITNESS_BODY_READ_WRITE = "https://www.googleapis.com/auth/fitness.body.write";
public static final java.lang.String FITNESS_NUTRITION_READ = "https://www.googleapis.com/auth/fitness.nutrition.read";
public static final java.lang.String FITNESS_NUTRITION_READ_WRITE = "https://www.googleapis.com/auth/fitness.nutrition.write";
private Scopes() { /* compiled code */ }
}
所以,开发人员认为,
“这些都是支持的范围,我所要做的就是参考a 带有
的有效范围Scopes.SCOPE_NAME
“
但是猜猜怎么着?范围内的故事还有更多内容!
原则上,您可以使用您要定位的Google API的端点创建自己的范围。就我而言,它是我使用的Contacts API,所以新代码看起来像这样:
GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
.requestServerAuthCode(CLIENT_ID, true)
.requestScopes(new Scope(Scopes.DRIVE_APPFOLDER), new Scope(Scopes.PROFILE), new Scope(Scopes.EMAIL), new Scope("https://www.google.com/m8/feeds/"))
.requestEmail()
.requestProfile()
.requestIdToken(CLIENT_ID)
.build();
您是否注意到了额外的范围:
new Scope("https://www.google.com/m8/feeds/")
是的,就是这样。这就是答案。
那么,究竟是什么刺激了我的蜘蛛侠意识?
您会看到,在Google提供的上述权限页面中,它没有提及有关“联系人”的任何内容。但是,我想访问联系人。那是一个明显的红旗!
添加其他范围后,它显示“想要管理您的联系人”。(您的aha!时刻)
最后一件事 -
我如何知道范围的URI?
嗯,这很简单。您最有可能在目标相应API的doc /指南中找到它。另外,请在提供的样本中注意。因此,下次您遇到身份验证时,请先查找正确的范围。