Аутентификация Facebook в UIWebView не перенаправляет обратно на исходную страницу моего сайта с просьбой авторизации - PullRequest
20 голосов
/ 06 ноября 2011

В нашем приложении для iOS у нас есть UIWebView, который показывает веб-контент в нашем домене с модулем комментариев Facebook.Модуль комментариев требует, чтобы пользователь вошел в Facebook.Когда пользователь нажимает кнопку входа, он проходит через вход, но никогда не перенаправляется обратно на нашу страницу.Они попадают на страницу, принадлежащую FB, которая просто сообщает пользователю «Вы вошли в систему».

Шаги воспроизведения:

  1. Создайте UIWebView в приложении iOS и разместитеМодуль комментариев Facebook на странице, размещенной на каком-либо вашем домене (например, http://foo.com/test.htm).
  2. ) Нажмите кнопку «Войти» в модуле комментариев и обратите внимание, что вы перенаправлены на вход FB.
  3. Войдитес действительными учетными данными FB и наблюдайте за тем, что происходит.

После того, как вы войдете в систему (шаг 3), я ожидаю, что после успешной аутентификации вы будете перенаправлены обратно на исходную страницу (например, http://foo.com/test.htm) чтобы вы могли продолжить взаимодействие. Однако этого не происходит.

Вместо этого вы находитесь на странице, принадлежащей FB, которая просто говорит что-то вроде «Вы сейчас вошли в систему», и вы попали туда.Перенаправление не происходит.

Это действительно ошибка или есть что-то еще, что я должен сделать, чтобы убедиться, что перенаправление происходит?

Ответы [ 4 ]

10 голосов
/ 25 февраля 2016

Если вы просто поддерживаете 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
    }
}
8 голосов
/ 06 апреля 2012

Я видел нечто похожее, что происходит с логинами FB других сайтов (например, Groupon), если вы загружаете их в UIWebView.Если это та же самая проблема (которая, я думаю, есть), она равна из-за того, что Facebook открывает окно входа в систему во всплывающем окне, как вы и предполагали.Что происходит в обычном браузере, так это то, что другое окно (всплывающее окно) открывается для входа в систему, а затем, когда пользователь входит в систему, это окно входа возвращается в исходное окно, чтобы сказать, что оно вошло в систему. Возможно, они используют EasyXDM или что-то подобное,Кажется, есть несколько уровней стратегии взаимодействия, включая Flash и postMessage.

. На iOS (и Android) это должно означать, что в конечном итоге он будет взаимодействовать с postMessage.Если вы отслеживаете URL, которые проходят через ваш 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.Теперь у вас есть два окна для работы.

К сожалению, этого все еще недостаточно, так как когда JavaScript на странице FB пытается запустить window.opener.postMessage или window.parent.postMessage, он не работает, потому что window.parent и window.opener не установлены на соответствующиеокно.Я не знаю хорошего способа сделать это в iOS (в отличие от этого, Android предоставляет соответствующий API для этого).

Способ, который я обошел, заключается в том, чтобы взломать объект JavaScript, чтобы обернуть ихзвонки.Примерно так:

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

Существует несколько способов вызова Objective-C из JavaScript, включая из официальных документов .Вы можете добавить этот код на страницу статического входа в FB, о которой я упоминал до использования stringByEvaluatingJavaScriptFromString:.Я не мог найти подходящее время для этого, поэтому я просто вставляю его после загрузки страницы и вызываю doFragmentSend(), который является методом FB JavaScript на той статической странице, который обычно вызывается при загрузке тела.

Итактеперь все, что нам нужно сделать, это передать эти данные в исходный UIWebView, вызвав postMessage.Это будет выглядеть примерно так:

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

Если вы еще не заметили, это огромный грязный хак, и я, вероятно, не рекомендовал бы его, если у вас нет альтернативы, но он работает длямне.

5 голосов
/ 26 ноября 2014

У меня была такая же проблема.Я понял, что после входа в Facebook компоненты UIWebView пусты, в нем нет html-кода.Я решил проблему, проверив содержимое компонента UIWebView в функции webViewDidFinishLoad и перезагрузив его содержимое, когда я обнаружил, что вход в Facebook приводит к появлению белого (пустой экран):

- (void)webViewDidFinishLoad:(UIWebView *)webView {
    if ( [[webView1 stringByEvaluatingJavaScriptFromString:
           @"document.body.innerHTML"] isEqualToString:@""] ) {
        [webView1 loadRequest:request]; //Define request as you want
    }
}
0 голосов
/ 16 мая 2016

В настоящее время в мобильном браузере браузер не поддерживает несколько окон по умолчанию.Альтернативное решение состоит в том, чтобы отслеживать успешное перенаправление с Facebook, например «close_popup.php? Reload = https://"», и перезагружать страницу. Также убедитесь, что вы сохранили значение комментария facebook перед запросом на вход, чтобы его можно было снова поместить в поле для комментариев..

...