fjcaetano / ReCaptcha

[In]visible ReCaptcha v2 for iOS
http://blog.flaviocaetano.com/post/recaptcha-reaches-1-dot-0/
MIT License
267 stars 133 forks source link

Validate method does not work #56

Closed nbob closed 5 years ago

nbob commented 6 years ago

Hello I am using ReCaptcha v1.3.1 and my validate calling has no effect.

Steps to reproduce:

  1. In didLoad I create my ReCaptcha instance in Controller
  2. Call validate method
  3. Don't see a WebView widget with google recaptcha quiz

Also I noticed that if I comment this if statement it works properly. With this modification I see Recaptcha widget on the screen and also get a response token in success callback. So debug tells me that didFinishLoading of ReCaptchaWebViewManager instance equals false and it returns immediately from the execute method.

Could you help me with this?

Thank a lot for lib.

fjcaetano commented 6 years ago

Hi @nbob, we need a bit more info to try and assess what may be going on here. The widget won't necessarily appear because it may be resolved "invisibly", therefore, have you checked if you're not receiving the token?

If not, what is happening? Nothing? Does the app simply halt? You mentioned that commenting a line of code has the desired effect, but were you able to receive the token after that?

Could you provide us some logs? Be careful and remove any sensitive data they may contain.

nbob commented 6 years ago

Sorry for a long response My code is almost the same as example code.

This is my controller

I have a layout only with a single button and handle a Tap Up event with printHello method. In this method I call a recaptcha.validate, but don't see grecaptcha widget and as result can not get a grecaptcha result.

You may check my logs bellow

2018-10-05 17:04:55.434419+0300 FoodTracker[30611:4924825] [MC] Lazy loading NSBundle MobileCoreServices.framework
2018-10-05 17:04:55.436199+0300 FoodTracker[30611:4924825] [MC] Loaded MobileCoreServices.framework
[JS LOG]: did load

Does the app simply halt?

No, app still works, but it stops manager.execute call at this point https://github.com/fjcaetano/ReCaptcha/blob/master/ReCaptcha/Classes/ReCaptchaWebViewManager.swift#L248

fjcaetano commented 5 years ago

@nbob sorry for the looong delay to reply.

It seems you're using the wrong baseURL. You should setup the same url/domain that is configured with your ReCaptcha key in Google's admin: https://www.google.com/recaptcha/admin

If this still doesn't solve your issue, it might be the case where we need a better algorithm to detect if ReCaptcha has already finished loading.

egv commented 5 years ago

We are having the same issues here, baseURL is ok, but from time to time recapthca is unable to detect if it is loaded.

Any ideas where we should start digging?

filip-a commented 5 years ago

I have 2 test devices, both of them running iOS 12.1. One is an iPhone XS and the second is a 7 Plus.

It works perfectly on the XS, but on the 7Plus it doesn't.

Even tried running the example project directly without any success on the 7Plus. Any ideas?

egv commented 5 years ago

Well, for me using new ReCaptcha object for each request did the trick. It failed when I tried to use one ReCaptcha for each request with resetOnError set to true. In that case I was seeing executing / resetting messages from js in console all the time.

fjcaetano commented 5 years ago

So, this is the reasoning behind that request logic:

After configuring the webview, we need to wait for its resources to be loaded before calling validate, otherwise the call to the JS function will be lost. The approach used to figure out if all resources were loaded was by monitoring the webview's requests and responses. However, it does load the same resource more than once, that's why we have a Set of active requests.

What might be happening is that we're flagging a request as active and never flag it as finished and that causes didFinishLoading to remain false. There is a number of reasons why we may not be able to detect the request has finished with the current logic:

  1. We're not handling errors in the webview.
  2. A request may finish with a different url (perhaps because of a redirect?)
  3. We're also not implementing every single method from WKNavigationDelegate.

Reading WKWebView's docs, there is a isLoading: Bool which is stated to be KVO compliant, so this might be a much simpler fix than monitoring network connections.

@egv, @filip-a and @nbob, are any of you willing to try test this spike as a possible fix? I ask you help because I can't promise I'll be able to look into this in time to be relevant for your projects, so your help would be much appreciated.

egv commented 5 years ago

I think I will be able to do this in the next couple of days myself or assign it it to someone on my team

fjcaetano commented 5 years ago

@egv I came up with a solution around WKWebView.estimatedProgress on PR #61 could you try checking out the branch to see if that solves your issue?