I'm trying to gain experience using retrofit/rxjava and I've decided to create an app that sort of mimics the Vimeo app. I am stuck on implementing the vimeo api's ouath authentication (also I'm aware that Vimeo has an Android SDK. I didn't want to use that since I wanted experience handling a REST service myself).
Basically I am trying to do this through a WebView. I believe that my logic is correct and I know that there is nothing wrong with my authorization url because it works in my laptop's web browser. However, in the app I am getting an error where after the user enters their login info on Vimeo's website, a page gets brought up that says "unauthorized - this action could not be completed because your form session expired. Please make sure that cookies are enabled."
And here is the segment of code that I've written to handle the webview logic:
@SuppressLint("SetJavaScriptEnabled")
public void onSignInMessageButtonClick() {
showSignInWebView(true);
mWebView.getSettings().setJavaScriptEnabled(true);
mWebView.getSettings().setJavaScriptCanOpenWindowsAutomatically(true);
mWebView.getSettings().setSupportMultipleWindows(true);
mWebView.getSettings().setUserAgentString("vimeo_test_app");
if (android.os.Build.VERSION.SDK_INT >= 21) {
CookieManager.getInstance().setAcceptThirdPartyCookies(mWebView, true);
CookieManager.getInstance().setAcceptCookie(true);
} else {
CookieManager.getInstance().setAcceptCookie(true);
}
mWebView.loadUrl("https://api.vimeo.com/oauth/authorize?client_id=" + VimeoClientCredentials.API_OAUTH_CLIENTID +
"&response_type=code&redirect_uri=" + VimeoClientCredentials.API_OAUTH_REDIRECT +
"&state=" + UUID.randomUUID().toString());
mWebView.setWebViewClient(new WebViewClient() {
public boolean shouldOverrideUrlLoading (WebView webView, String url) {
Log.i(TAG, "shouldOverrideUrlLoading called: " + url);
Uri uri = Uri.parse(url);
if (uri.toString().startsWith(VimeoClientCredentials.API_OAUTH_REDIRECT)) {
webView.stopLoading();
webView.loadUrl("about:blank");
String code = Uri.parse(url).getQueryParameter("code");
if (code != null) {
mUserPresenter.getOauthToken(code, VimeoClientCredentials.API_OAUTH_REDIRECT);
}
else {
showUnauthorizedError();
}
return true;
}
return false;
}
});
}
Has anyone else experienced this issue?
UPDATE: It appears this is an issue with cookies being set in WebView. I turned off cookies on my laptop's web browser and attempted the oauth process, and got the same error. From reading solutions on StackOverflow it appears I'm enabling cookies on the WebView correctly, so not sure what is going wrong.
After a lot of trial and error it looks like my overriding of the user agent was causing this issue. Here's the problem line:
mWebView.getSettings().setUserAgentString("vimeo_test_app");
I had previously added that line of code to get around the fact that Google sign in doesn't work through WebView. Here's the final code with all unneeded lines removed:
@SuppressLint("SetJavaScriptEnabled")
public void onSignInMessageButtonClick() {
showSignInWebView(true);
String authUrl = "https://api.vimeo.com/oauth/authorize?client_id=" + VimeoClientCredentials.API_OAUTH_CLIENTID +
"&response_type=code&redirect_uri=" + VimeoClientCredentials.API_OAUTH_REDIRECT +
"&state=" + UUID.randomUUID().toString();
mWebView.getSettings().setJavaScriptEnabled(true);
mWebView.loadUrl(authUrl);
if (android.os.Build.VERSION.SDK_INT >= 21) {
CookieManager.getInstance().setAcceptThirdPartyCookies(mWebView, true);
} else {
CookieManager.getInstance().setAcceptCookie(true);
}
mWebView.setWebViewClient(new WebViewClient() {
public boolean shouldOverrideUrlLoading (WebView webView, String url) {
if (url.startsWith(VimeoClientCredentials.API_OAUTH_REDIRECT)) {
webView.stopLoading();
webView.loadUrl("about:blank");
showSignInWebView(false);
String code = Uri.parse(url).getQueryParameter("code");
if (code != null) {
mUserPresenter.getOauthToken(code, VimeoClientCredentials.API_OAUTH_REDIRECT);
}
else {
showUnauthorizedError();
}
return true;
}
return false;
}
});
}