Basic認証が必要なWebページをiOSのWebViewで表示する
Swift版のサンプルが見つからなかったので、共有します。
(あったら、シカトしてください。)
Basic認証処理について
Basic認証とは、
ユーザ名とパスワードは暗号化やハッシュ化がされていない状態で送信する認証方法です。
一番簡易な方法で、盗聴・改ざんされやすい。
WebとiOSの挙動の違い
Webの場合、ブラウザで表示しようとすると、
Basic認証が必要な場合、ダイアログが表示され、
ユーザ名とパスワードを聞かれますが、
iOSネイティブのWebViewで表示しようとすると、
真っ白で何も表示されませんでした。
didFailLoadWithErrorも呼ばれていないようです。
実装方針
NSURLConnectionを利用する例を記載します。
iOS9で非推奨なので、iOS9以上サポートする方は、NSURLSessionをご利用ください
サンプルコード
class ViewController: UIViewController,UIWebViewDelegate {
let userId = "xxxx"
let password = "yyyyyyyy"
let reqestUrl: String = "http://xxxx/yyyy/zzzz"
@IBOutlet weak var webView: UIWebView!
override func viewDidLoad() {
super.viewDidLoad()
webView.delegate = self
registerCredential()
}
func registerCredential() {
let connection = NSURLConnection(request: NSURLRequest(URL: NSURL(string: reqestUrl)!), delegate: self)
connection?.start()
}
//MARK:- NSURLConnection
func connection(connection:NSURLConnection!, willSendRequestForAuthenticationChallenge challenge:NSURLAuthenticationChallenge!) {
let creds = NSURLCredential(user: userId, password: password, persistence: NSURLCredentialPersistence.Permanent)
challenge.sender?.useCredential(creds, forAuthenticationChallenge: challenge)
}
func connectionDidFinishLoading(connection: NSURLConnection) {
webView.loadRequest(NSURLRequest(URL: NSURL(string: reqestUrl)!))
}
/**
認証が必要な場合に呼ばれるメソッド
*/
func connection(connection: NSURLConnection, didReceiveAuthenticationChallenge challenge: NSURLAuthenticationChallenge?){
//パスワードを間違えると無限ループするため
guard challenge?.proposedCredential == false else {
connection.cancel()
return
}
let credential = NSURLCredential(user: "user", password: "password", persistence: NSURLCredentialPersistence.ForSession)
challenge?.sender?.useCredential(credential, forAuthenticationChallenge: challenge!)
}
}
解説
認証が必要なページを表示しようとすると
「didReceiveAuthenticationChallenge」が呼ばれるようです。
ちなみに、Basic認証を間違えると、無限ループするので、
既に設定されている場合は、キャンセルしてしています。
まとめ
Basic認証をあまり使う機会はないかもしれませんが、
誰かの参考なれば幸いです。
今度Digest認証もやってみようと思います。
さいごに
間違っている箇所があれば、優しい方教えて下さい。