Javascript 如何使用WKWebView进行用户身份验证?

Javascript 如何使用WKWebView进行用户身份验证?,javascript,ios,iphone,swift,Javascript,Ios,Iphone,Swift,目标:检索accessToken和用户详细信息,而不使用任何本机控件输入用户凭据。使用SSO登录进行相同的操作 步骤:iOS应用程序和用户执行 1.用户选择SSO登录选项 2.用户重定向到SSO登录URL 3.SSO登录URL显示用于输入用户名和密码的JavaScript警报 密码。(在桌面和移动浏览器上,它不会显示任何内容。) 在webview中) 4.一旦用户输入凭据,他将被重定向到我们的服务器,该服务器返回包含用户数据的html页面 我尝试过的: 尝试使用以下命令 func viewDid

目标:检索accessToken和用户详细信息,而不使用任何本机控件输入用户凭据。使用SSO登录进行相同的操作

步骤:iOS应用程序和用户执行

1.用户选择SSO登录选项

2.用户重定向到SSO登录URL

3.SSO登录URL显示用于输入用户名和密码的JavaScript警报 密码。(在桌面和移动浏览器上,它不会显示任何内容。) 在webview中)

4.一旦用户输入凭据,他将被重定向到我们的服务器,该服务器返回包含用户数据的html页面

我尝试过的: 尝试使用以下命令

func viewDidLoad(){
        let pref = WKPreferences()
        pref.javaScriptEnabled = true
        pref.javaScriptCanOpenWindowsAutomatically = true

        /* Create a config using pref*/
        let configuration = WKWebViewConfiguration()
        configuration.preferences = pref

        /* Instantiate the web view */

        let webviewFrame = CGRect(x:0,y: txtSSOLoginUrl.bounds.maxY, width: self.view.bounds.width, height: self.view.bounds.height - 40)
        webView = WKWebView(frame:webviewFrame,configuration: configuration)
        view.addSubview(webView)
        webView.navigationDelegate = self
        webView.uiDelegate  = self
        webView.load(request as URLRequest)
}

extension SSOLoginViewController:WKUIDelegate,WKNavigationDelegate{
    func webView(_ webView: WKWebView, didStartProvisionalNavigation navigation: WKNavigation!) {
        UIApplication.shared.isNetworkActivityIndicatorVisible = true
        print("DID START NAV didStartProvisionalNavigation")

    }
    func webView(_ webView: WKWebView, didReceiveServerRedirectForProvisionalNavigation navigation: WKNavigation!) {
        print("RECEIVERD SERVER REDIRECT")

    }

    func webView(_ webView: WKWebView, didFailProvisionalNavigation navigation: WKNavigation!, withError error: Error) {
        print("EERRORRR : \(error)")
    }


    func webView(_ webView: WKWebView, didFail navigation: WKNavigation!, withError error: Error) {
        print ("ERRRRRR : \(error)")
    }

    func webView(_ webView: WKWebView, runJavaScriptAlertPanelWithMessage message: String, initiatedByFrame frame: WKFrameInfo, completionHandler: @escaping () -> Void) {
        print("runJavaScriptAlertPanelWithMessage")
        let alertController = UIAlertController(title: nil, message: message, preferredStyle: .actionSheet)

        alertController.addAction(UIAlertAction(title: "Ok", style: .default, handler: { (action) in
            completionHandler()
        }))

        self.present(alertController, animated: true, completion: nil)
        alertController.popoverPresentationController?.sourceView = self.view
    }

    func webView(_ webView: WKWebView, runJavaScriptConfirmPanelWithMessage message: String, initiatedByFrame frame: WKFrameInfo, completionHandler: @escaping (Bool) -> Void) {
        print("runJavaScriptConfirmPanelWithMessages")
        let alertController = UIAlertController(title: nil, message: message, preferredStyle: .actionSheet)

        alertController.addAction(UIAlertAction(title: "Ok", style: .default, handler: { (action) in
            completionHandler(true)
        }))

        alertController.addAction(UIAlertAction(title: "Cancel", style: .default, handler: { (action) in
            completionHandler(false)
        }))

        self.present(alertController, animated: true, completion: nil)

        alertController.popoverPresentationController?.sourceView = self.view
    }

    func webView(_ webView: WKWebView, runJavaScriptTextInputPanelWithPrompt prompt: String, defaultText: String?, initiatedByFrame frame: WKFrameInfo, completionHandler: @escaping (String?) -> Void) {
        print("runJavaScriptTextInputPanelWithPrompt")
        let alertController = UIAlertController(title: nil, message: prompt, preferredStyle: .actionSheet)

        alertController.addTextField { (textField) in
            textField.text = defaultText
        }
        alertController.addAction(UIAlertAction(title: "Ok", style: .default, handler: { (action) in
            if let text = alertController.textFields?.first?.text {
                completionHandler(text)
            } else {
                completionHandler(defaultText)
            }

        }))
        alertController.addAction(UIAlertAction(title: "Cancel", style: .default, handler: { (action) in

            completionHandler(nil)

        }))

        self.present(alertController, animated: true, completion: nil)
        alertController.popoverPresentationController?.sourceView = self.view
    }

    func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
        UIApplication.shared.isNetworkActivityIndicatorVisible = false
        print("DID FINISH NAV didFinish navigation")

    }

    func webView(_ webView: WKWebView, decidePolicyFor navigationResponse: WKNavigationResponse, decisionHandler: @escaping (WKNavigationResponsePolicy) -> Void) {
        print("DECIDE POLICY WKNavigationResponse \(navigationResponse)")
        decisionHandler(.allow)

    }

    func webView(_ webView: WKWebView, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) {
        print("DID RECEIVE URLAuthenticationChallenge")
         //var cred = URLCredential(user: "username", password: "Password123!", persistence: URLCredential.Persistence.none)
         //challenge.sender?.use(password, for: challenge)
        completionHandler(URLSession.AuthChallengeDisposition.useCredential, nil)

    }
 }
输出 未看到询问用户凭据的警报

预期产出
获取用户名和密码文本字段的警报以输入凭据。

我们解决此问题的方法是,我们使用了一个由服务器提供服务的HTML页面,后端使用隐藏字段中所需的详细信息进行实际重定向。该重定向URL被提供给使用自己SSO登录的另一方,但通过我们的应用程序,在web视图中。这不是问题的解决方案,而是一种变通方法。从来没有真正解决过这个问题。

为了解决这个问题,我们使用了一个由服务器提供服务的HTML页面,后端在隐藏字段中使用所需的详细信息进行实际重定向。该重定向URL被提供给使用自己SSO登录的另一方,但通过我们的应用程序,在web视图中。这不是问题的解决方案,而是一种变通方法。从未真正解决过此问题。

有任何特定原因不想使用
SFSafariViewController
?SFSafariViewController不工作。试过了。到目前为止这个问题有什么解决办法吗?这个问题解决了吗。你能帮个忙吗?我也有同样的问题。不,但我们用了不同的方式,我们创建了一个服务器页面,服务器在处理SSO身份验证后重定向到该页面,我们只是从隐藏字段中读取所需的详细信息。您是否有任何不想使用
SFSafariViewController
?SFSafariViewController不起作用。试过了。到目前为止这个问题有什么解决办法吗?这个问题解决了吗。你能帮我一下吗?我也遇到了同样的问题。没有,但是我们用了另一种方式,我们创建了一个服务器页面,服务器在处理SSO身份验证后重定向到该页面,我们只是从隐藏字段中读取所需的详细信息。