UIWebView中的Facebook身份验证不会重定向到我的网站上的原始页面,要求验证 [英] Facebook authentication in a UIWebView does not redirect back to original page on my site asking for auth

查看:216
本文介绍了UIWebView中的Facebook身份验证不会重定向到我的网站上的原始页面,要求验证的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我们的iOS应用中,我们有一个UIWebView,它显示了我们的域上具有Facebook注释模块的网页内容。评论模块要求用户使用Facebook登录。当用户单击登录按钮时,它们将通过登录流程进行,但不会重定向到我们的页面。他们最终在FB拥有的网页上,只是告诉用户您现在已经登录。

In our iOS app, we have a UIWebView that shows web content on our domain that has a Facebook comment module. The comment module requires that the user is signed in with facebook. When user clicks on the sign in button, they are taken through the sign in flow, but are never redirect back to our page. They end up on an FB owned page that just tells the user "You are now signed in".

Repro步骤:


  1. 在iOS应用程序中创建UIWebView,并在您拥有的某个域上托管的页面上托管一个Facebook注释模块(例如 http://foo.com/test.htm )。

  2. 点击注释模块上的登录按钮,并注意您重定向到FB签名

  3. 使用有效的FB凭据登录并观察会发生什么。

  1. Create a UIWebView in an iOS app, and host a Facebook comment module on a page hosted on some domain you own (e.g. http://foo.com/test.htm).
  2. Click on the Sign In button on the comment module and notice you are redirect to FB sign in.
  3. Sign in with valid FB credentials and observe what happens.

签署后在(步骤3)中,我希望在成功的身份验证后,您将被重定向回到原始页面(例如 http://foo.com/ test.htm ),以便您可以继续进行交互。但是,这并没有发生。

After you sign in (step 3) I would expect that after a successful authentication, you are redirected back to the original page (e.g http://foo.com/test.htm) so you can continue your interaction. However, this isn't happening.

相反,你是在FB拥有的页面上,只是说你现在登录了,你被困在那里。没有重定向发生。

Instead, you are on an FB owned page that just says something like "You are now signed in" and you are trapped there. No redirect happens.

这是否真的是一个错误,还是有其他一些我应该做的,以确保重定向发生?

Is this indeed a bug or is there something else I should be doing to ensure the redirect happens?

推荐答案

我已经看到类似的事情发生在其他网站的FB登录(例如Groupon),如果你加载它们在一个 UIWebView 。如果这是同样的问题(我认为是这样),那么由于Facebook在你怀疑的弹出窗口中打开了登录窗口,所以它是。正常浏览器会发生什么情况是打开另一个窗口(弹出窗口)进行登录,然后当用户登录时,该登录窗口会回传到原始窗口,以表示它已经登录。他们可能使用EasyXDM或类似的东西。似乎有几层沟通策略,包括Flash和 postMessage

I've seen something similar happen with other sites' FB logins (e.g. Groupon) if you load them in a UIWebView. If this is the same problem (which I think it is), it is due to Facebook opening up the login window in a popup as you suspected. What happens on a normal browser is that another window (popup) is opened for login, and then when the user logs in, that login window communicates back to the original window to say that it has logged in. They probably use EasyXDM or something similar. There seem to be a few layers of strategies to communicate including Flash and postMessage.

在iOS(和Android)这意味着它将最终与 postMessage 进行通信。如果您跟踪通过您的 UIWebView 的网址,您应该会在近期看到类似的内容:

On iOS (and Android) this should mean it'll end up communicating with postMessage. If you track the URLs that go through your UIWebView you should see something like this near the end:

https://s-static.ak.fbcdn.net/connect/xd_proxy.php#<lots of stuff>&relation=opener&transport=postmessage&<lots more stuff>

UIWebView 不支持多个窗口它不能 postMessage 返回到您的原始页面,因为它不再加载。您可以做的是检测 UIWebView 是否尝试加载FB登录页面,并将其加载到单独的 UIWebView 。现在你有两个窗口可以使用。

UIWebView doesn't support multiple windows so it can't postMessage back to your original page since it's no longer loaded. What you can do is detect when the UIWebView is trying to load the FB login page and load that in a separate UIWebView. Now you have two windows to work with.

不幸的是,这还不够,因为FB的页面上的JavaScript尝试运行 window.opener.postMessage window.parent.postMessage 它不起作用,因为 window.parent 窗口。开启者未设置为相应的窗口。我不知道在iOS中做一个很好的方法(相反,Android为此提供了适当的API)。

Unfortunately, this is still not enough as when the JavaScript on FB's page tries to run window.opener.postMessage or window.parent.postMessage it doesn't work because window.parent and window.opener aren't set to the appropriate window. I don't know of a good way to do this in iOS (in contrast Android provides a proper API for this).

我的工作方式是打开一个JavaScript对象来包装这些调用。如下所示:

The way I've worked around this is to hack up a JavaScript object to wrap these calls. Something like:

window.opener={};
window.opener.postMessage = function(data,url) {
    // signal your code in objective-c using some strategy
};
window.parent = window.opener;

有几种方法可以从JavaScript调用Objective-C,包括这个来自官方文档。在使用 stringByEvaluatingJavaScriptFromString: 。我找不到一个很好的时间来做到这一点,所以我只是在页面加载后注入它,并调用 doFragmentSend(),这是通常在静态页面上的FB JavaScript方法被调用身体负载。

There are a few ways you can call Objective-C from JavaScript including this one from the official docs. You can inject this code into that static FB login page I mentioned before using stringByEvaluatingJavaScriptFromString:. I couldn't find a good time to do this, so I just inject it after page load and call doFragmentSend() which is the FB JavaScript method on that static page that normally gets called on body load.

所以现在我们需要做的是将这些数据传递到原始的 UIWebView 通过调用 postMessage 。看起来像这样:

So now all we need to do is pass on this data into the original UIWebView by calling postMessage. It'll look something like this:

NSString *post = [NSString stringWithFormat:@"window.postMessage('%@', '*');", data];
[webView stringByEvaluatingJavaScriptFromString:post];

如果你现在还没有注意到,这是一个巨大的凌乱的黑客,我可能不会推荐它除非你没有别的选择,但它是为我工作。

If you haven't noticed by now, this is a huge messy hack and I probably wouldn't recommend it unless you have no alternative, but it's worked for me.

这篇关于UIWebView中的Facebook身份验证不会重定向到我的网站上的原始页面,要求验证的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆