LoginSignup
12
16

More than 3 years have passed since last update.

WKWebViewにBasic認証を正しく実装する

Last updated at Posted at 2019-03-18

WKWebViewにBasic認証を正しく実装する

WKWebViewにBasic認証を実装するサンプルコードです。

環境
Xcode10.1

最終的なサンプルを見たいならこちら

WebViewの生成

WKWebViewを生成しdelegateの設定を行います。
認証に関するdelegateは navigationDelegate です。(WKWebViewには uiDelegateもあるので気をつけて。)

以下はコードで生成する例です(Storyboardでも問題なし)。

ViewController.swift
import UIKit
import WebKit

class ViewController: UIViewController {

    var webView: WKWebView!

    override func loadView() {
        view = UIView(frame: .zero)

        let configuration = WKWebViewConfiguration()
        webView = WKWebView(frame: .zero, configuration: configuration)
        webView.translatesAutoresizingMaskIntoConstraints = false
        webView.navigationDelegate = self
        view.addSubview(webView)

        NSLayoutConstraint.activate([
            webView.topAnchor.constraint(equalTo: view.topAnchor),
            webView.leftAnchor.constraint(equalTo: view.leftAnchor),
            webView.bottomAnchor.constraint(equalTo: view.bottomAnchor),
            webView.rightAnchor.constraint(equalTo: view.rightAnchor)
            ])
    }

}

extension ViewController: WKNavigationDelegate {
}

認証のdelegateを実装

認証に関するdelegateメソッドを実装します。
まずは何もしないメソッドを書きます。

ViewController.swift
extension ViewController: WKNavigationDelegate {

    public func webView(_ webView: WKWebView, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) {
        switch challenge.protectionSpace.authenticationMethod {
        default:
            completionHandler(.performDefaultHandling, nil)
        }
    }

}

Basic認証の処理を実装

認証に関するdelegateメソッドは、Basic認証に限らず他の認証でも呼ばれます。
Basic認証の場合の処理と、それ以外の処理を分けて実装します。

URLCredentialにIDとPasswordを設定して、completionHandlerを呼び出します。

ViewController.swift
extension ViewController: WKNavigationDelegate {

    public func webView(_ webView: WKWebView, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) {
        switch challenge.protectionSpace.authenticationMethod {
        case NSURLAuthenticationMethodHTTPBasic:
            let credential = URLCredential(user: "user", password: "password", persistence: URLCredential.Persistence.forSession)
            completionHandler(.useCredential, credential)

        default:
            completionHandler(.performDefaultHandling, nil)
        }
    }

}

サンプル

UIAlertControllerでユーザー人入力を求める場合の最終的なコードは以下になります。

IDとPasswordを入力したとき、キャンセルしたとき、そのそれぞれでcompletionHandlerを呼び出します。

ViewController.swift
import UIKit
import WebKit

class ViewController: UIViewController {

    var webView: WKWebView!

    override func loadView() {
        view = UIView(frame: .zero)

        let configuration = WKWebViewConfiguration()
        webView = WKWebView(frame: .zero, configuration: configuration)
        webView.translatesAutoresizingMaskIntoConstraints = false
        webView.navigationDelegate = self
        view.addSubview(webView)

        NSLayoutConstraint.activate([
            webView.topAnchor.constraint(equalTo: view.topAnchor),
            webView.leftAnchor.constraint(equalTo: view.leftAnchor),
            webView.bottomAnchor.constraint(equalTo: view.bottomAnchor),
            webView.rightAnchor.constraint(equalTo: view.rightAnchor)
            ])
    }

    override func viewDidLoad() {
        let request = URLRequest(url: URL(string: "https://hogehoge.com/")!)
        webView.load(request)
    }
}

extension ViewController: WKNavigationDelegate {

    public func webView(_ webView: WKWebView, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) {
        switch challenge.protectionSpace.authenticationMethod {
        case NSURLAuthenticationMethodHTTPBasic:

            let alert = UIAlertController(title: "Basic認証", message: "ユーザ名とパスワードを入力してください", preferredStyle: .alert)
            alert.addTextField {
                $0.placeholder = "user"
            }
            alert.addTextField {
                $0.placeholder = "password"
                $0.isSecureTextEntry = true
            }

            let login = UIAlertAction(title: "ログイン", style: .default) { (_) in
                guard
                    let user = alert.textFields?[0].text,
                    let password = alert.textFields?[1].text
                    else {
                        completionHandler(.cancelAuthenticationChallenge, nil)
                        return
                }
                let credential = URLCredential(user: user, password: password, persistence: URLCredential.Persistence.forSession)
                completionHandler(.useCredential, credential)
            }
            let cancel = UIAlertAction(title: "キャンセル", style: .cancel) { (_) in
                completionHandler(.cancelAuthenticationChallenge, nil)
            }
            alert.addAction(login)
            alert.addAction(cancel)

            present(alert, animated: true, completion: nil)

        default:
            completionHandler(.performDefaultHandling, nil)
        }
    }

}
12
16
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
12
16