Implementing Auto-Login in WKWebView with JavaScript

Auto-login functionality simplifies the user authentication process by automatically filling in the login credentials and submitting the login form on behalf of the user. By doing this, users can log in to the app more quickly and efficiently by not having to manually enter their username and password each time they access it.

Through the utilization of WKWebView and JavaScript in Swift, developers can effectively incorporate auto-login features into their iOS applications, offering users a seamless login process. Whether it’s an e-commerce website, social media platform, or banking app, auto-login increases user satisfaction and promotes continuous app usage.

Additionally, auto-login enhances security by reducing the possibility of credential theft that comes with manually entering login information. Developers can use JavaScript injection to safely autofill the login form while guaranteeing that private user data is encrypted and kept safe. Using JavaScript to implement auto-login in WKWebView gives developers more flexibility and control over the login process, while also improving security and user convenience. Depending on particular user scenarios and preferences, developers can modify the auto-login logic to provide a customized experience for various user segments.

Here are the steps to use JavaScript in Swift to implement auto-login functionality on a WKWebView and include it in your project:

1. Create a new Swift project

To begin, open Xcode and create a new iOS project by selecting the App template.

2. Add a WKWebView to your ViewController

Launch Main. storyboard, drag a WKWebView onto your ViewController, and in your ViewController class, create an IBOutlet for it Or take WebView Programmatically you can take a reference from this tutorial https://codegeekworld.com/building-a-basic-browser-using-wkwebview/ for it.

Choose WebKit View because Web View is deprecated now.

import UIKit
import WebKit

class ViewController: UIViewController, WKNavigationDelegate {
    
    @IBOutlet weak var webView: WKWebView?
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        webView.navigationDelegate = self
        
        if let url = URL(string: "https://example.com/login") {
            let request = URLRequest(url: url)
            webView.load(request)
        }
    }
}
    
    

WebKit framework provides classes and protocols for embedding web content in iOS applications using the WKWebView class.

Add WWKNavigationDelegate is a protocol used for managing and handling navigation-related events in a WKWebView.

The WKNavigationDelegate protocol provides methods for managing navigation-related events, such as the loading and redirection of web content, in a WKWebView. When implementing a web login process, it’s essential to handle redirection events, as they often occur during the authentication process. Here’s an explanation of how to implement WKNavigationDelegate methods to handle redirection in the login process:

Implement WKNavigationDelegate Methods:

1. webView(_:decidePolicyFor:decisionHandler:):

When a web view navigation action is about to happen, this method is called. It offers the option to approve or reject the navigation action according to certain standards like the URL being navigated to. This method of handling redirection involves looking at the URL to see if it points to a different page—like a successful login page—or something else entirely.

func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
    // Check if the navigation action indicates a redirection
    if let url = navigationAction.request.url, url.absoluteString.contains("successful_login_url") {
        // Redirected to successful login URL, handle accordingly
        print("Login successful!")
        // Perform necessary actions for successful login
    }
    
    // Allow or cancel the navigation action based on criteria
    decisionHandler(.allow) // or .cancel
}

With this approach, you ascertain whether the URL in the navigation action includes a particular string (“successful_login_url”), which denotes a successful redirection of login. If so, you handle the redirection appropriately by making changes to the user interface or carrying out extra tasks. Next, you call the decisionHandler closure with the appropriate policy (WKNavigationActionPolicy.allow or WKNavigationActionPolicy.cancel) to determine whether to allow or cancel the navigation action.

2. webView(_:didFailProvisionalNavigation:withError:) (Optional):

This method is called when a web view navigation fails to load due to an error during the provisional navigation. It allows you to handle errors that occur during the redirection process, such as network errors or invalid URLs.

func webView(_ webView: WKWebView, didFailProvisionalNavigation navigation: WKNavigation!, withError error: Error) {
    // Handle navigation failure with error
    print("Navigation failed with error: \(error.localizedDescription)")
}

This method is used to provide error handling for cases where the redirection fails due to network issues or other errors.

3. Load Web Content

In the viewDidLoad method of your ViewController, load the web content into the WKWebView.

First, we load the web content that contains the login form to implement auto-login functionality within a WKWebView in our iOS app using Swift. This is an important step because it sets up the framework for the JavaScript injection that will be used for auto-login.

We create a URLRequest object with the URL of the login page or web form and use it to load web content into the WKWebView. This URL usually leads to the web application or service login page that users must authenticate with.

We use the load(_: URLRequest) method to tell the WKWebView instance to load the web content after the URLRequest has been created. Using this method, the WKWebView starts retrieving the web content from the server by launching an asynchronous request to load the given URL.

Note:- the loading process is asynchronous, meaning that the web content may take some time to load, especially if it involves fetching resources such as images, stylesheets, or scripts from external sources.

4. Inject JavaScript for Auto-Login

The next step is to inject JavaScript code that will automate the login process once the web content containing the login form has been loaded into the WKWebView. To fill in the login information and submit the form on the user’s behalf, this entails programmatically running JavaScript code inside the WKWebView.

To run JavaScript code inside the web content loaded in the WKWebView, we use the evaluateJavaScript(_:completionHandler:) method in Swift, which is offered by the WKWebView class. The given JavaScript code is evaluated asynchronously in the context of the currently loaded web page by this method, which may or may not return a result to the completion handler.

We create a JavaScript code snippet that targets the login form elements (password and username fields, for example) based on their HTML IDs or other distinguishing characteristics to implement auto-login functionality. Next, we programmatically submit the login form and populate these form fields with the user’s credentials using JavaScript.

let userName = ""
let password = ""
let str1 = "javascript:(function(){var element = document.getElementsByName('username')\n" + "element[0].focus()\n" +
            "document.execCommand('insertText', true, '\(userName)')\n})()"
            self.myWebView?.evaluateJavaScript(str1) { (result, error) in
      if let result = result {
    }
 }

 let str2 = "javascript:(function(){var element = document.getElementsByName('password')\n" +
            "element[0].focus()\n" +
            "document.execCommand('insertText', true, '\(password)')\n})()"
            self.myWebView?.evaluateJavaScript(str2) { (result, error) in
      if let result = result {
    }
  }

The supplied code is made up of two JavaScript injection snippets (str1 and str2) that are specifically designed to automate filling out a web form’s username and password fields, respectively.

str1:

focuses on the input element for the username by using element[0].focus().

  1. The username field on the web form is the main focus of this JavaScript snippet. The following tasks are completed by it:

2. Retrieves the username input element from the web form using document.getElementsByName('username').

3. Implement the document. To add the supplied userName variable value to the username input field, use the execCommand(‘insertText’, true, ‘\(userName)’) command.

str2:

Likewise, the password field on the web form is the target of this JavaScript snippet. While it concentrates on the password input element and enters the password variable value into the password input field, it proceeds in the same manner as str1.

Evaluation of JavaScript Injection

After constructing the JavaScript injection snippets (str1 and str2), the evaluateJavaScript(_:completionHandler:) method of the WKWebView instance (self.myWebView) is invoked to execute each snippet within the context of the loaded web page.

let str4 =  "javascript:(function(){document.querySelectorAll('button[type=submit]')[0].click()\n})()"
            self.myWebView?.evaluateJavaScript(str4) { (result, error) in
                if let result = result {
   }
 }
  1. selects every button element on the page that has the attribute type set to submit by using document.querySelectorAll(‘button[type=submit]’).

2. Accesses the first element in the NodeList using [0].

3. uses the button element’s click() method to programmatically mimic a click action.

This JavaScript injection script is designed to mimic a click on a form’s submit button on a loaded web page. This action can initiate form submission, which includes submitting the previously entered login credentials and completing the login procedure.

Invoking evaluateJavaScript(_:completionHandler:)

After constructing the JavaScript injection snippet (str4), the evaluateJavaScript(_:completionHandler:) method of the WKWebView instance (self.myWebView) is invoked to execute the snippet within the context of the loaded web page.

self.myWebView?.evaluateJavaScript(str4) { (result, error) in
    if let result = result {
    }
}

The JavaScript code given in the snippet (str4) is executed asynchronously by this method while the loaded web page is in context. The snippet locates and activates the submit button, which starts the desired action (such as submitting a form), by interacting with the Document Object Model (DOM) of the webpage.

import UIKit
import WebKit

class ViewController: UIViewController, WKNavigationDelegate {
    
    @IBOutlet weak var webView: WKWebView!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        webView.navigationDelegate = self
        
        if let url = URL(string: "https://WebViewTesting.com/login") {
            let request = URLRequest(url: url)
            webView.load(request)
        }
    }
    
    func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
        let jsCode = """
        let userName = ""
let password = ""
let str1 = "javascript:(function(){var element = document.getElementsByName('username')\n" + "element[0].focus()\n" +
            "document.execCommand('insertText', true, '\(userName)')\n})()"
            self.myWebView?.evaluateJavaScript(str1) { (result, error) in
      if let result = result {
    }
 }

 let str2 = "javascript:(function(){var element = document.getElementsByName('password')\n" +
            "element[0].focus()\n" +
            "document.execCommand('insertText', true, '\(password)')\n})()"
            self.myWebView?.evaluateJavaScript(str2) { (result, error) in
      if let result = result {
    }
  }
let str4 =  "javascript:(function(){document.querySelectorAll('button[type=submit]')[0].click()\n})()"
            self.myWebView?.evaluateJavaScript(str4) { (result, error) in
                if let result = result {
   }
 }
    
 webView.evaluateJavaScript(jsCode) { (result, error) in
     if let error = error {
          print("Error injecting JavaScript: \(error.localizedDescription)")
            }
        }
    }
    
    // Handle redirection if needed
    func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
        // Implement redirection handling logic
        decisionHandler(.allow)
    }
}

Conclusion

Implementing auto-login functionality on a WKWebView using JavaScript in Swift can greatly enhance the user experience of your iOS application. By following the outlined steps, you can seamlessly integrate this feature into your project. you can successfully implement auto-login functionality on a WKWebView in your iOS application, enhancing user convenience and streamlining the login experience.

If you have any queries Please Comment Below.

Thank you!

Leave a Reply

Your email address will not be published. Required fields are marked *