UIWebView中的Facebook身份验证不会重定向回我的站点上询问auth的原始页面

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (68)

在我们的iOS应用程序中,我们有一个UIWebView,它显示我们域上的Web内容,其中有一个Facebook评论模块。注释模块要求用户使用Facebook登录。当用户单击“登录”按钮时,它们会通过“流”中的标志进行处理,但绝不会重定向回我们的页面。它们最终出现在FB拥有的页面上,该页面只告诉用户“现在已登录”。

复制步骤:

  1. 在iOS应用程序中创建一个UIWebView,并在拥有的某个域上的页面上托管一个Facebook评论模块
  2. 单击注释模块上的“登录”按钮,并注意您正在重定向到FB登录。
  3. 使用有效的FB凭据登录并观察发生的情况。

在登录(步骤3)之后,我希望在成功的身份验证之后,将被重定向回原始页面。

相反,你在一个FB拥有的页面上,上面写着“你现在签了名”,你被困在那里了。不发生重定向。

这是否确实是一个错误,还是我应该做一些其他的事情来确保重定向的发生?

提问于
用户回答回答于

只是支持IOS 8及以上版本,则可以使用WKWebView已经实现了@kabuko:

// Container view including the main WKWebView
var container : UIView?
var popupWebView : WKWebView?

override func viewDidLoad() {
    super.viewDidLoad()

    let prefs = WKPreferences()
    prefs.javaScriptEnabled = true
    // allow facebook to open the login popup
    prefs.javaScriptCanOpenWindowsAutomatically = true

    let config = WKWebViewConfiguration()
    config.preferences = prefs

    webView = WKWebView(frame: container.frame, configuration: config)
    webView?.UIDelegate = self
    webView?.navigationDelegate = self
}

// callback if the content of the webView wants to create a new window
func webView(webView: WKWebView, createWebViewWithConfiguration configuration: WKWebViewConfiguration, forNavigationAction navigationAction: WKNavigationAction, windowFeatures: WKWindowFeatures) -> WKWebView? {
    // create new popup webview and add it to the view hierarchy
    popupWebView = WKWebView(frame: container.frame, configuration: configuration)
    container.addSubview(popupWebView!)
    return popupWebView
}

func webView(webView: WKWebView, didFinishNavigation navigation: WKNavigation!) {
    // if the main webView loads a new page (e.g. due to succesful facebook login)
    // remove the popup
    if (popupWebView != nil) {
        popupWebView?.removeFromSuperview()
        popupWebView = nil
    }
}
用户回答回答于

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

在iOS(和Android)上,这意味着它最终将与postMessage。如果您跟踪通过UIWebView你应该看到这样的东西接近尾声:

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。现在有两个窗口可以使用。

不幸的是,这还远远不够,因为FB页面上的JavaScript试图运行window.opener.postMessagewindow.parent.postMessage它不起作用是因为window.parentwindow.opener没有设置到适当的窗口。

我所做的工作就是黑出一个JavaScript对象来包装这些调用。类似于:

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

有几种方法可以从JavaScript调用Object-C,可以将此代码插入到我在前面提到的静态fb登录页中。stringByEvaluatingJavaScriptFromString:.。我找不到合适的时间来做这件事,所以我只是在页面加载和调用之后注入它doFragmentSend()它是静态页面上的FBJavaScript方法,通常在Body Load上被调用。

所以现在我们要做的就是把这些数据传递到UIWebView打电话postMessage。看起来会是这样的:

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

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

扫码关注云+社区