目标:使用Uber API SSO登录,检索授权令牌,在TokenManager中存储身份验证令牌。但首先,我很高兴获得令牌。 假设:我的应用程序将在安装了Uber应用程序的Androids上运行。
考虑到客观和假设 - 我相信我不需要"后端"那是对的吗?一旦我获得了身份验证令牌,我将通过SSO使用它来请求乘坐。
我在下面发布了我的代码。请帮忙。 (我注释掉了onResume代码,因为,现在,我只是想让初始登录工作。)我的代码主要基于Uber提供的样本here
我有一个优步API客户端ID,因为我填充了优步开发者网站here我也将我的AndroidDebug哈希密钥发布到此网站。
我的手机上安装了Uber。
当我在手机上运行下面的应用程序(不是模拟器)并点击按钮时,有时会出现黑色Uber-logo应用程序屏幕,变为白色并无限期挂起。 有时会出现一个白色屏幕,说连接有问题。当我按下UBer-present" Okay"按钮Uber屏幕恢复到我的应用程序。我的应用程序捕获错误(请参阅onLoginError)并将其Toast to" INVALID_APP_SIGNATURE"运行Android Studio我无法使用断点捕获返回值。英国石油公司已经确定但它从未开火。
BTW我知道至少部分Uber API凭证是正确的。我使用Postman来请求令牌并提供scope = request并获得令牌。但是,我认识到通过Postman这样做可能不会打击Uber API SSO。
根据我的阅读,上面的错误字符串以及应用程序的反应方式,这看起来像一个openSSL / hash / key问题,但我的hashkey适用于Facebook登录。
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mGoButton = (Button) findViewById(R.id.goBtn);
configuration = new SessionConfiguration.Builder()
.setClientId(CLIENT_ID)
.setRedirectUri(REDIRECT_URI)
.setScopes(Arrays.asList(Scope.RIDE_WIDGETS, Scope.REQUEST, Scope.PROFILE))
.setEnvironment(SessionConfiguration.Environment.PRODUCTION)
//.setEnvironment(SessionConfiguration.Environment.SANDBOX)
.build();
accessTokenStorage = new AccessTokenManager(getApplicationContext());
accessTokenManager = new AccessTokenManager(getApplicationContext());
Long expirationTime = 2592000L;
List<Scope> scopes = Arrays.asList(Scope.RIDE_WIDGETS);
String token = "obtainedAccessToken";
String refreshToken = "obtainedRefreshToken";
String tokenType = "obtainedTokenType";
accessToken = new AccessToken(expirationTime, scopes, token, refreshToken, tokenType);
accessTokenStorage.setAccessToken(accessToken);
//Use a custom button with an onClickListener to call the LoginManager directly
loginManager = new LoginManager(accessTokenManager,
new SampleLoginCallback(),
configuration,
CUSTOM_BUTTON_REQUEST_CODE);
loginManager.setRedirectForAuthorizationCode(true);
mGoButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
loginManager.login(MainActivity.this);
}
});
}
@Override
protected void onResume() {
super.onResume();
//if (loginManager.isAuthenticated()) {
// loadProfileInfo();
//}
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
Log.i(LOG_TAG, String.format("onActivityResult requestCode:[%s] resultCode [%s]",
requestCode, resultCode));
loginManager.onActivityResult(this, requestCode, resultCode, data);
}
private class SampleLoginCallback implements LoginCallback {
@Override
public void onLoginCancel() {
Toast.makeText(MainActivity.this, R.string.user_cancels_message, Toast.LENGTH_LONG).show();
}
@Override
public void onLoginError(@NonNull AuthenticationError error) {
int a = 1;
Toast.makeText(MainActivity.this,
getString(R.string.login_error_message, error.name()), Toast.LENGTH_LONG)
.show();
}
@Override
public void onLoginSuccess(@NonNull AccessToken accessToken) {
loadProfileInfo();
}
@Override
public void onAuthorizationCodeReceived(@NonNull String authorizationCode) {
Toast.makeText(MainActivity.this, getString(R.string.authorization_code_message, authorizationCode),
Toast.LENGTH_LONG)
.show();
}
}
当我在我的环境中复制/粘贴代码时的Sasa(Android Studio)我得到下面的红线/错误,因为它将LoginManger调用中的第一个参数更改为tokenStorage vs tokenManager。 IDE将错误称为必需参数和提供的参数之间的不匹配。
这是我的构建gradle
答案 0 :(得分:1)
我设法重现了你的问题。问题肯定在于生成签名证书的哈希值。
要获取签名证书的哈希值,请运行此命令,其中包含密钥的别名和密钥库的路径:
keytool -exportcert -alias androiddebugkey -keystore 〜/ .android / debug.keystore | openssl sha1 -binary | openssl base64
默认情况下,调试密钥库的密码为空。
也不确定为什么你有两个AccessTokenManager实例。您的代码应如下所示:
configuration = new SessionConfiguration.Builder()
.setClientId(CLIENT_ID)
.setRedirectUri(REDIRECT_URI)
.setScopes(Arrays.asList(Scope.RIDE_WIDGETS, Scope.REQUEST, Scope.PROFILE))
.setEnvironment(SessionConfiguration.Environment.PRODUCTION)
//.setEnvironment(SessionConfiguration.Environment.SANDBOX)
.build();
accessTokenStorage = new AccessTokenManager(this);
loginManager = new LoginManager(accessTokenStorage,
new SampleLoginCallback(),
configuration,
CUSTOM_BUTTON_REQUEST_CODE);
loginManager.setRedirectForAuthorizationCode(true);
customButton = (Button) findViewById(R.id.custom_uber_button);
customButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
loginManager.login(LoginSampleActivity.this);
}
});
我添加了新按钮&#34;测试登录&#34; - 执行上面的代码 - 然后进入Scope Authorization页面 - 并完成身份验证。
登录示例应用程序的构建gradle文件如下所示:
buildscript {
repositories {
jcenter()
google()
}
dependencies {
classpath deps.build.gradlePlugins.android
}
}
apply plugin: 'com.android.application'
android {
compileSdkVersion deps.build.compileSdkVersion
buildToolsVersion deps.build.buildToolsVersion
defaultConfig {
minSdkVersion deps.build.minSdkVersion
targetSdkVersion deps.build.targetSdkVersion
buildConfigField "String", "CLIENT_ID", "\"${loadSecret("UBER_CLIENT_ID")}\"" //Add your client id to gradle.properties
buildConfigField "String", "REDIRECT_URI", "\"${loadSecret("UBER_REDIRECT_URI")}\"" //Add your redirect uri to gradle.properties
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_7
targetCompatibility JavaVersion.VERSION_1_7
}
}
dependencies {
compile project(':rides-android')
compile deps.support.appCompat
}
/**
* Loads property from gradle.properties and ~/.gradle/gradle.properties
* Use to look up confidential information like keys that shoudln't be stored publicly
* @param name to lookup
* @return the value of the property or "MISSING"
*/
def loadSecret(String name) {
return hasProperty(name) ? getProperty(name) : "MISSING"
}