Created
September 8, 2020 13:15
-
-
Save jkereako/d111ff6f4594873d409d3194371d6732 to your computer and use it in GitHub Desktop.
ReCAPTCHA v2 in Swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html> | |
<head> | |
<meta charset="utf-8" /> | |
<meta name="viewport" content="width=device-width, initial-scale=1" /> | |
<script src="https://www.google.com/recaptcha/api.js?onload=onLoad&render=explicit&hl=en" async defer></script> | |
<title></title> | |
<script type="text/javascript"> | |
const post = function(value) { | |
window.webkit.messageHandlers.recaptcha.postMessage(value); | |
}; | |
console.log = function(message) { | |
post(message); | |
}; | |
var onLoad = function() { | |
grecaptcha.render( | |
"recaptcha", | |
{ | |
sitekey: "${siteKey}", | |
callback: function(token) { | |
post(token); | |
}, | |
size: "normal" | |
} | |
); | |
}; | |
</script> | |
</head> | |
<body> | |
<div id="recaptcha"></div> | |
</body> | |
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import UIKit | |
import WebKit | |
final class ReCAPTCHAViewController: UIViewController { | |
private var webView: WKWebView! | |
private let viewModel: ReCAPTCHAViewModel | |
init(viewModel: ReCAPTCHAViewModel) { | |
self.viewModel = viewModel | |
super.init(nibName: nil, bundle: nil) | |
} | |
required init?(coder: NSCoder) { | |
fatalError("init(coder:) has not been implemented") | |
} | |
override func loadView() { | |
let webConfiguration = WKWebViewConfiguration() | |
let contentController = WKUserContentController() | |
contentController.add(viewModel, name: "recaptcha") | |
webConfiguration.userContentController = contentController | |
webView = WKWebView(frame: .zero, configuration: webConfiguration) | |
view = webView | |
} | |
override func viewDidLoad() { | |
super.viewDidLoad() | |
navigationItem.leftBarButtonItem = UIBarButtonItem( | |
barButtonSystemItem: .close, | |
target: self, | |
action: #selector(didSelectCloseButton) | |
) | |
webView.loadHTMLString(viewModel.html, baseURL: viewModel.url) | |
} | |
} | |
// MARK: - Target-Actions | |
private extension ReCAPTCHAViewController { | |
@IBAction func didSelectCloseButton() { | |
dismiss(animated: true) | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import WebKit | |
protocol ReCAPTCHAViewModelDelegate: class { | |
func didSolveCAPTCHA(token: String) | |
} | |
final class ReCAPTCHAViewModel: NSObject { | |
weak var delegate: ReCAPTCHAViewModelDelegate? | |
var html: String { | |
guard let filePath = Bundle.main.path( | |
forResource: "recaptcha", ofType: "html" | |
) else { | |
assertionFailure("Unable to find the file.") | |
return "" | |
} | |
let contents = try! String( | |
contentsOfFile: filePath, encoding: .utf8 | |
) | |
return parse(contents, with: ["siteKey": siteKey]) | |
} | |
let siteKey: String | |
let url: URL | |
/// Creates a ReCAPTCHAViewModel | |
/// - Parameters: | |
/// - siteKey: ReCAPTCHA's site key | |
/// - url: The URL for registered with Google | |
init(siteKey: String, url: URL) { | |
self.siteKey = siteKey | |
self.url = url | |
super.init() | |
} | |
} | |
// MARK: - WKScriptMessageHandler | |
extension ReCAPTCHAViewModel: WKScriptMessageHandler { | |
func userContentController(_ userContentController: WKUserContentController, | |
didReceive message: WKScriptMessage) { | |
guard let message = message.body as? String else { | |
assertionFailure("Expected a string") | |
return | |
} | |
delegate?.didSolveCAPTCHA(token: message) | |
} | |
} | |
private extension ReCAPTCHAViewModel { | |
func parse(_ string: String, with valueMap: [String: String]) -> String { | |
var parsedString = string | |
valueMap.forEach { key, value in | |
parsedString = parsedString.replacingOccurrences( | |
of: "${\(key)}", with: value | |
) | |
} | |
return parsedString | |
} | |
} |
What is the reason to not use reCAPTCHA Enterprise ? there is the same limit as I can see 1,000,000 views per month?
I think need iOS Target 14.x for reCAPTCHA Enterprise
How can I Observe Expired Sessions?
https://www.google.com/recaptcha/api/siteverify?secret=your_secret&response=response_token
Use this GET api for timeout status validation. Replace your_secret
& response_token
Is this possible to generate a delegate method like didSolveCAPTCHA?
If yes, then how can I achieve that?
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
thanks it work fine in my case,but it show retapcha code everytime while access via web did not completely invisibe. any suggestion why?