Android 处理 Oauth2 身份验证 - 无法在 WebView 上启用 cookie
Android Handling Oauth2 authentication - Can't enable cookies on WebView
我正在努力获得使用 retrofit/rxjava 的经验,我决定创建一个类似于 Vimeo 应用程序的应用程序。我坚持实施 vimeo api 的 ouath 身份验证(我也知道 Vimeo 有一个 Android SDK。我不想使用它,因为我想体验自己处理 REST 服务).
基本上我试图通过 WebView 来完成此操作。我相信我的逻辑是正确的,我知道我的授权 url 没有任何问题,因为它可以在我笔记本电脑的网络浏览器中运行。但是,在应用程序中我收到一个错误,用户在 Vimeo 的网站上输入他们的登录信息后,会弹出一个页面,上面写着 "unauthorized - this action could not be completed because your form session expired. Please make sure that cookies are enabled."
下面是我为处理 webview 逻辑而编写的代码段:
@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;
}
});
}
还有其他人遇到过这个问题吗?
更新:
看来这是在 WebView 中设置 cookie 的问题。我在笔记本电脑的网络浏览器上关闭了 cookie 并尝试了 oauth 过程,但得到了同样的错误。通过阅读 Whosebug 上的解决方案,我似乎正确地在 WebView 上启用了 cookie,所以不确定出了什么问题。
经过大量试验和错误后,似乎我对用户代理的覆盖导致了这个问题。这是问题行:
mWebView.getSettings().setUserAgentString("vimeo_test_app");
我之前添加了那行代码来解决 Google 无法通过 WebView 登录的问题。这是删除了所有不需要的行的最终代码:
@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;
}
});
}
我正在努力获得使用 retrofit/rxjava 的经验,我决定创建一个类似于 Vimeo 应用程序的应用程序。我坚持实施 vimeo api 的 ouath 身份验证(我也知道 Vimeo 有一个 Android SDK。我不想使用它,因为我想体验自己处理 REST 服务).
基本上我试图通过 WebView 来完成此操作。我相信我的逻辑是正确的,我知道我的授权 url 没有任何问题,因为它可以在我笔记本电脑的网络浏览器中运行。但是,在应用程序中我收到一个错误,用户在 Vimeo 的网站上输入他们的登录信息后,会弹出一个页面,上面写着 "unauthorized - this action could not be completed because your form session expired. Please make sure that cookies are enabled."
下面是我为处理 webview 逻辑而编写的代码段:
@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;
}
});
}
还有其他人遇到过这个问题吗?
更新: 看来这是在 WebView 中设置 cookie 的问题。我在笔记本电脑的网络浏览器上关闭了 cookie 并尝试了 oauth 过程,但得到了同样的错误。通过阅读 Whosebug 上的解决方案,我似乎正确地在 WebView 上启用了 cookie,所以不确定出了什么问题。
经过大量试验和错误后,似乎我对用户代理的覆盖导致了这个问题。这是问题行:
mWebView.getSettings().setUserAgentString("vimeo_test_app");
我之前添加了那行代码来解决 Google 无法通过 WebView 登录的问题。这是删除了所有不需要的行的最终代码:
@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;
}
});
}